假设我有一堆文件,其命名如下:
file01.txt file02.txt file03.txt ... file20.txt
并且我想对这些文件进行一系列的执行命令。
我知道如果想将“file05.txt”中的“rm”到“file09.txt”,我可以这样做:
rm file0[5-9].txt
但是我如何才能 'rm' 从 file08.txt 到 file13.txt 的范围?我试过这个代码
rm file[08-13].txt
但它不起作用。我可以运行这个命令:
rm file0[89].txt file1[0-3].txt
但如果可能的话,我想知道是否可以只使用一个更精细的“rm”参数来做到这一点。
答案1
您需要使用括号扩展bash
:
rm file{08..13}.txt
这将删除文件file08
,file13
如果缺少任何文件将显示错误消息。
设置范围以满足您的需要。
通配符的问题[]
在于它将其内部的每个字符/数字视为单个标记,因此仅支持使用单个数字进行范围声明。
如果你坚持使用[]
,你可以使用这个相当丑陋的模式来file08
匹配file13
:
rm file0[8-9].txt file1[0-3].txt
答案2
某些 shell,例如 Ubuntu 的默认 shell /bin/sh
(即dash
)或 mksh
没有括号扩展,或者在ksh
- 括号扩展的情况下不能使用填充零:
$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13
在这种情况下,我们可以利用来printf
格式化文件名的数字部分,并使用 while 循环来实现类似 c 的 for 循环行为(注意用echo
或rm
任何你想要的来替换):
$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt
而且这相当便携 -也适用于dash
、ksh
、 。在和的情况下,我们还可以使用mksh dash`):mksh
bash
ksh
bash
c-style for loop syntax (but not in case of
or
$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt
请注意,在bash
的情况下,printf
支持打印到变量,因此我们可以printf -v num "%.2d" "$i"
不用命令替换。