从`find`循环文件名?

Sea*_*ene 4 linux shell loops find

如果我运行此命令:

sudo find . -name *.mp3
Run Code Online (Sandbox Code Playgroud)

然后我可以获得许多mp3文件的列表.

现在我想在循环中对每个mp3文件做一些事情.例如,我可以创建一个while循环,并在内部为变量分配第一个文件名file.然后我可以用那个文件做点什么.接下来,我可以将第二个文件名分配给变量file并使用它,等等.

如何使用linux shell命令实现这一点?任何帮助表示赞赏,谢谢!

Jer*_*err 15

为此,使用read内置:

sudo find . -name *.mp3 |
while read filename
do
    echo "$filename"    # ... or any other command using $filename
done
Run Code Online (Sandbox Code Playgroud)

如果您的文件名不使用newline(\n)字符,这应该可以正常工作.

  • 您可以使用`-print0`选项进行查找,使用`-d''选项来解决`\n`问题.另外,使用`-r`选项进行读取,因此文件名中的反斜杠不会被解释为转义序列. (8认同)
  • 抱歉,为什么是 `sudo`?除了无用之外,它是危险的,可能无法与用户绑定的声音基础设施(即pulseaudio)一起使用 (2认同)

seh*_*ehe 10

我最喜欢的是

find . -name '*.mp3' -exec cmd {} \;
Run Code Online (Sandbox Code Playgroud)

要么

find . -name '*.mp3' -print0 | xargs -0 cmd
Run Code Online (Sandbox Code Playgroud)

而Loop

正如其他人所指出的那样,你可以经常使用while read循环来逐行读取文件名,它的缺点是不允许文件名中的行尾(谁使用它?).

xargs-exec cmd {} +

总结评论说-exec... +更好,我更喜欢xargs,因为它更通用:

  • 与其他命令一起使用 find
  • 允许在命令行中"批处理"(分组),比如说xargs -n 10(一次十个)
  • 允许并行化,比如说xargs -P4(一次运行最多4个并发进程)
  • 保密分离(例如在OP的情况下,他使用sudo find:使用-exec将以root用户身份运行所有命令,而xargs没有必要:

    sudo find -name '*.mp3' -print0 | sudo xargs -0 require_root.sh
    sudo find -name '*.mp3' -print0 | xargs -0 nonroot.sh
    
    Run Code Online (Sandbox Code Playgroud)
  • 通常,管道更通用(日志记录,排序,远程处理,缓存,检查,并行化等,你可以这样做)