我想使用bash在多个子目录中的各种扩展名的文件名中插入一个整数。
示例:
./trial2/foo.hhh
-> ./trial2/foo1.hhh
./trial2/trial3/foo.txt
-> ./trial2/trial3/foo1.txt
我试图将文件名与扩展名分开,并在其中插入整数,并使用:
i=123
find . -type f -exec sh -c ' echo mv "$0" "${0%.*}${i}.${0##*.}" ' {} \;
mv ./trial2/foo.hhh ./trial2/foo.hhh
但是未打印变量输出${i}
。为什么?
如果我更改为:
find . -type f -exec sh -c ' mv "$0" "${0%.*}123.${0##*.}" ' {} \;
mv ./trial2/foo.hhh ./trial2/foo123.hhh
数字已打印。但是,我需要变量${i}
,因为它将在包装for循环中定义。
答案 0 :(得分:2)
您快到了;您只是碰到了引用的微妙之处。 i
在当前shell中声明,因此需要以某种方式传递到sh
运行的find
中。在您当前的命令中,${i}
用单引号引起来,因此在将引用的材料传递给bash
之前,sh
不会对其进行解释。
如查尔斯·达菲(Charles Duffy)所建议:
find . -type f -exec sh -c ' echo mv "$0" "${0%.*}${1}.${0##*.}" ' {} "$i" \;
在sh
命令中,$0
是{}
。 $1
是sh
的第二个参数,它是"$i"
(i
扩展为单个单词)。 ${i}
代替sh
,使用${1}
访问该参数(i
的副本)。
在此示例中,i
插值到当前shell中。
Before: find . -type f -exec sh -c ' echo mv "$0" "${0%.*}${i}.${0##*.}" ' {} \;
After: find . -type f -exec sh -c ' echo mv "$0" "${0%.*}'"${i}"'.${0##*.}" ' {} \;
^^ ^^
'"${i}"'
使您脱离单引号,然后展开i
,然后将您带回单引号。这样,您传递给sh
的命令将包含您想要的i
的值。
答案 1 :(得分:1)
通过$i
中的$0
,以及$1
及之后的文件名,您可以从-exec ... {} \;
更改为-exec ... {} +
,因此仅使用一个{ {1}}实例可以重命名多个文件。
以下内容需要使用bash,但会生成sh
命令,即使存在恶意文件名或令人困惑的文件名(包括空格,换行符,控制字符等),这些命令也能保证正确无误:
mv