Linux 从“find”循环文件名?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9391003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:44:21  来源:igfitidea点击:

Loop over file names from `find`?

linuxshellloopsfind

提问by Searene

If I run this command:

如果我运行这个命令:

sudo find . -name *.mp3

then I can get a listing of lots of mp3 files.

然后我可以得到很多 mp3 文件的列表。

Now I want to do something with each mp3 file in a loop. For example, I could create a whileloop, and inside assign the first file name to the variable file. Then I could do something with that file. Next I could assign the second file name to the variable fileand do with that, etc.

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

How can I realize this using a linux shell command? Any help is appreciated, thanks!

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

采纳答案by Jeremy Kerr

For this, use the readbuiltin:

为此,请使用read内置:

sudo find . -name *.mp3 |
while read filename
do
    echo "$filename"    # ... or any other command using $filename
done

Provided that your filenames don't use the newline (\n) character, this should work fine.

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

回答by Some programmer dude

How about using the -execoption to find?

使用-exec选项查找怎么样?

find . -name '*.mp3' -exec mpg123 '{}' \;

That will call the command mpg123for every file found, i.e. it will play all the files, in the order they are found.

这将为mpg123找到的每个文件调用该命令,即它将按照找到的顺序播放所有文件。

回答by Mallik

for file in $(sudo find . -name *.mp3);
do
    # do something with file
done

回答by sehe

My favourites are

我最喜欢的是

find . -name '*.mp3' -exec cmd {} \;

or

或者

find . -name '*.mp3' -print0 | xargs -0 cmd


While Loop

While 循环

As others have pointed out, you can frequently use a while readloop to read filenames line by line, it has the drawback of not allowing line-ends in filenames (who uses that?).

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

xargsvs. -exec cmd {} +

xargs对比 -exec cmd {} +

Summarizing the comments saying that -exec...+is better, I prefer xargs because it is more versatile:

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

  • works with other commands than just find
  • allows 'batching' (grouping) in command lines, say xargs -n 10(ten at a time)
  • allows parallellizing, say xargs -P4(max 4 concurrent processes running at a time)
  • does privilige separation (such as in the OP's case, where he uses sudo find: using -execwould run all commands as the root user, whereas with xargsthat isn't necessary:

    sudo find -name '*.mp3' -print0 | sudo xargs -0 require_root.sh
    sudo find -name '*.mp3' -print0 | xargs -0 nonroot.sh
    
  • in general, pipes are just more versatile (logging, sorting, remoting, caching, checking, parallelizing etc, you can do that)

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

    sudo find -name '*.mp3' -print0 | sudo xargs -0 require_root.sh
    sudo find -name '*.mp3' -print0 | xargs -0 nonroot.sh
    
  • 一般来说,管道只是更通用(日志记录、排序、远程处理、缓存、检查、并行化等,你可以这样做)