n.s*_*.st 11 linux bash xargs wildcards
我有一个包含编号文件的目录,例如 1_foo.txt 2_bar.asc 13_test.png,并希望使用尽可能简单的 bash 命令将它们移动到单独的目录(例如 1、2 和 13)中。
创建编号目录很容易:
mkdir $(seq 1 15)
Run Code Online (Sandbox Code Playgroud)
我还想出了一个命令来将文件复制到各自的目录中:
seq 15 -1 1 | xargs -I@ mv @_* @
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用,因为 * 与 xargs 一起使用时被解释为普通字符,给我这样的错误:“mv: File '15_*' not found.”。
有什么简单的方法可以在 xargs 调用的命令中使用 * 作为通配符吗?
Sco*_*ott 26
你非常接近。
seq 15 -1 1 | xargs -I@ sh -c 'mv @_* @'
Run Code Online (Sandbox Code Playgroud)
您需要将 的解释(扩展)延迟*
到@发生替换之后。(但你已经明白这就是问题所在,对吗?)
有人建议我永远不要将未知文件名(或其他替换字符串)直接嵌入到 shell 命令行中。上面的示例可能相当安全,因为您知道字符串将是什么 —
15、14、... 3、2和1。但是将上面的示例用作更复杂命令的模板可能很危险。更安全的安排是
seq 15 -1 1 | xargs -I@ sh -c 'mv -- "$1"_* "$1"' x-sh @
Run Code Online (Sandbox Code Playgroud)
wherex-sh是一个半任意字符串,用于标记调用的 shell 发出的任何错误消息。这等效于我的第一个示例,不同之处在于,它不是将字符串(由 表示@)直接嵌入到 shell 命令中,而是通过将@用作 shell 的参数来注入它们,然后将它们引用为"$1"。
PS 您建议seq反向运行命令 ( seq 15 -1 1, 生成15, 14, ..., 3, 2,1
而不是1, 2, 3, ..., 14, 15) 并且没有人提到它。如果您的文件名像1foo.txt、2bar.asc、 和13test.png等(在数字之后出现各种字符,而不是总是_),这将是答案的重要部分。在这种情况下,命令将是mv "$1"* "$1"(没有_),而且,如果你这样做1,然后再命令mv 1* 1
将横扫了所有的10quick*,11brown*,12fox*,等文件,随着1foo*文件。但
seq 1 15 | xargs -I@ sh -c 'mv -- "$1"_* "$1"' x-sh @
Run Code Online (Sandbox Code Playgroud)
应该是安全的。
PPSseq命令不是由 POSIX 指定的。壳中的大括号扩展也不是。一个POSIX兼容的解决方案可通过将构建grawity的这个问题的答案
与此其他答案由亚当·卡茨:
i=1
while [ "$i" -le 15 ]
do
mv -- "${i}"_* "$i"
i=$((i+1))
done
Run Code Online (Sandbox Code Playgroud)
PPPS 当您知道文件名以字母数字字符(即字母和数字)开头时,这并不重要,但在更一般的情况下,您应该--在命令名和参数之间使用。这改进了以破折号开头的文件名的处理。该 --告诉命令来治疗参数(文件名)
作为 参数。
没有它,这样的参数可能会被视为选项字符串。
只是不要xargs用于那个。使用for循环:
for i in $(seq 1 15); do
mv ${i}_* $i
done
Run Code Online (Sandbox Code Playgroud)
更好的是使用大括号扩展而不是seq:
mkdir {1..15}
for i in {1..15}; do
mv ${i}_* $i
done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8961 次 |
| 最近记录: |