我需要一个 shell 脚本,它将一些字符串添加到目录和子目录中存在的文件名(.c 文件)中。
例如:如果lokesh
是父目录并且在它里面lokesh1
,lokesh2
是子目录和里面lokesh1
( 1.c
, 2.c
...) 和里面lokesh2
( a.c
, b.c
...)。因此,在运行脚本后,我想将其更改为 ( x_1.c
, x_2.c
... ) 和(x_a.c,
x_b.c
...)。
注意:在编写以下内容时,我使用的是 OpenBSD find
,-execdir utility {} ';'
它将替换{}
为找到的文件的基本名称。对于 GNU find
, the{}
也将是找到的文件的基本名称,但它会另外加上./
,这会使find
下面的第一个命令无用。对于 GNU 用户find
(例如,大多数使用 Linux 的人),向下滚动到解决方案的其他变体。
您想查找.c
目录中或lokesh
目录下的所有文件,并在其名称前加上x_
.
find lokesh -type f -name '*.c' -execdir echo mv {} x_{} ';'
Run Code Online (Sandbox Code Playgroud)
在-type f
和-name '*.c'
表情会发现所有的相关文件,同时-execdir mv {} x_{} ';'
将重命名找到的文件。
该-execdir
表达式不是标准的,但大多数实现都find
支持它。它的不同之处在于-exec
给定的实用程序是以找到的路径名的父目录作为工作目录来执行的。因此{}
,命令行中的 将是我们要重命名的文件的基本名称(而不是像 一样的完整路径名-exec
)。
运行一次,然后echo
当你看到它做正确的事情时删除它。这echo
将阻止mv
实际重命名文件。
在不支持-execdir
(或-execdir
不像 OpenBSD 那样支持)的系统上:
find lokesh -type f -name '*.c' \
-exec sh -c 'for name do echo mv "$name" "${name%/*}/x_${name##*/}"; done' sh {} +
Run Code Online (Sandbox Code Playgroud)
或者,更短但效率稍低,
find lokesh -type f -name '*.c' \
-exec sh -c 'echo mv "$1" "${1%/*}/x_${1##*/}"' sh {} ';'
Run Code Online (Sandbox Code Playgroud)
这两种变体都使用了一个简短的 shell 脚本,最终基本上做同样的事情:
mv "$name" "${name%/*}/x_${name##*/}"
Run Code Online (Sandbox Code Playgroud)
这会将给定完整路径名的文件移动到同一目录中$name
以 为前缀的新名称中x_
。的${name%/*}
参数替换等同于$( dirname "$name" )
,并给该路径名的父目录,而${name##*/}
等同于$( basename "$name" )
这将给路径名的基名(文件名分量)。