为了将子文件夹中的所有文件移动到当前文件夹中,我使用了这个脚本
while read f
do
mv "$f" .
done < file_list
Run Code Online (Sandbox Code Playgroud)
这个伟大的工程,但我不得不产生file_list与
find . -name *.avi > file_list
Run Code Online (Sandbox Code Playgroud)
我想要的是将命令直接添加到我的 while 循环中
while read f
do
mv "$f" .
done < find . -name *.avi
Run Code Online (Sandbox Code Playgroud)
但是 bash 告诉我 -bash: syntax error near unexpected token `.'
将 find 命令通过管道传输到我的 while 循环中的简单解决方案是什么?
ter*_*don 20
您在这里不需要任何循环,find可以为您完成:
find . -name '*.avi' -exec mv {} . \;
Run Code Online (Sandbox Code Playgroud)
您还可以使用进程替换。
while IFS= read -r f
do
mv -- "$f" .
done < <(find . -name '*.avi' )
Run Code Online (Sandbox Code Playgroud)
在像 一样的 shell 中bash,与管道方法相比,它的优点是不在子 shell 中运行循环,因此您在循环中执行的变量分配不会在之后丢失。在bash(或zsh)中,您宁愿这样做:
while IFS= read <&3 -rd '' f
do
mv -- "$f" .
done 3< <(find . -name '*.avi' -print0)
Run Code Online (Sandbox Code Playgroud)
使用 NUL 分隔符能够处理任意文件名,使用 fd 3 而不是 0mv可能会提示用户并读取标准输入上的答案,find如果您使用 0 ,这将是输出。
或者使用find命令本身
find . -name '*.avi' -exec mv -t . {} +
Run Code Online (Sandbox Code Playgroud)
使用+意味着我们一次传递许多参数,mv从而不必为mv每个文件运行一次调用。-t是一个 GNU 扩展。对于其他mv实现,您可以将其更改为:
find . -name '*.avi' -exec sh -c 'exec mv "$@" .' sh {} +
Run Code Online (Sandbox Code Playgroud)
正确的方法是管道
find . -name '*.avi' |
while read f
do
mv "$f" .
done
Run Code Online (Sandbox Code Playgroud)
第一个命令“ find . -name *.avi”的结果将提供给第二个命令。
这是调用管道(来自符号|)。您可以将管道视为临时文件,例如
find . -name '*.avi' > file1.tmp
while read f
do
mv "$f" .
done < file1.tmp
rm file1.tmp
Run Code Online (Sandbox Code Playgroud)
正如指出的带有空格或换行符的文件名可能会导致错误。
如果唯一的目的是移动文件,请使用@Terdon 的命令。
此外,您必须引用,*.avi否则它会在第二次运行时中断。
find: paths must precede expression: `foo.avi'
find: possible unquoted pattern after predicate `-name'?
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1761 次 |
| 最近记录: |