我想要做的是重命名当前树中任意位置的文件夹,而不一定直接重命名工作目录中的文件夹。我需要做的是:
- “A 1”变成“A 01”
- “A 2”变成“A 02”
- “A 09”被忽略
我最终得到了这个:
find . -type d -regex '.*A [0-9]$' -execdir mv "{}" "$(echo '{}' | sed 's_[0-9]_0&_')" \;
为了测试这一点,我稍微降低了复杂性:
find . -type d -regex '.*A [0-9]$' -execdir echo "$(echo '{}' | sed 's_[0-9]_0&_')" \;
find
列出了我想要的所有文件夹,但中的模式sed
似乎在文件夹名称中找不到匹配项。如果它单独执行,它会起作用,所以我猜想需要转义的字符存在问题。
答案1
更新:添加了一个可以处理任何/所有有效文件名字符的版本,除了\x01
用作 sed 分隔符的 之外......我已经A.*
在更新示例,因为我正在测试A"'
。当然,只需更改为您需要的任何内容即可。
findx="\(.*/\)\(A.* \)\([0-9]\)$"
replx="&\x00\1\20\3\x00"; I=$'\x01'
find . -depth -type d -regex "$findx" |
sed -n "s$I$findx$I$replx$I p" |
tr -d '\n' |
xargs --verbose -0n2 mv
perl
下面是一个使用而不是 的示例sed
。
请注意perl 的正则表达式PCRE
并不完全相同posix 扩展 ERE
如find
本例中所使用的。但它们确实具有足够的共同点,因此在本例中可以使用相同的正则表达式模式。
export findx='(.*/)(A.* )([0-9])$'
find . -depth -type d -regextype posix-extended -regex "$findx" |
perl -l000pe 's/$ENV{'findx'}/$_\000$1${2}0$3/' |
xargs --verbose -0n2 mv
下一个版本无法处理文件名中的单引号'
。
使用标准正则表达式模式
regex='\(.*/\)\(A \)\([0-9]\)$'
find . -depth -type d -regex "$regex" |
sed -n "s|$regex|'&' '\1\20\3'|p" |
xargs --verbose -n2 mv
使用扩展正则表达式模式
regex='(.*/)(A )([0-9])$'
find . -depth -regextype posix-extended -type d -regex "$regex" |
sed -nr "s|$regex|'&' '\1\20\3'|p" |
xargs --verbose -n2 mv
需要该-depth
选项,以便更深入地在重命名任何父目录之前,先重命名嵌套目录。
请注意,该脚本不会测试是否已经存在与新名称同名的目录。