如何使用bash对目录中的每个文件执行某些操作?

18 bash shell

我从这开始:

command *
Run Code Online (Sandbox Code Playgroud)

但是当目录为空时它不起作用;*通配符成为文字"*"字符.所以我改用这个:

for i in *; do
   ...
done
Run Code Online (Sandbox Code Playgroud)

哪个有效,但同样,如果目录为空则不行.我使用ls:

for i in `ls -A`
Run Code Online (Sandbox Code Playgroud)

但是当然,然后将包含空格的文件名拆分.我尝试了-Q开关:

for i in `ls -AQ`
Run Code Online (Sandbox Code Playgroud)

这导致名称仍然被拆分,只在名称的开头和结尾有一个引号字符.我在这里遗漏了一些明显的东西,还是比它应该更难?

小智 43

假设您只想对文件执行某些操作,那么简单的解决方案是测试$ i是否为文件:

for i in * 
do
    if test -f "$i" 
    then
       echo "Doing somthing to $i"
    fi
done
Run Code Online (Sandbox Code Playgroud)

你应该总是进行这样的测试,因为你几乎肯定不想以同样的方式处理文件和目录.请注意"$ i"周围的引号,以防止文件名包含空格的问题.


Bom*_*mbe 12

find 可能是你想要的.

find . | while read file; do
    # do something with $file
done
Run Code Online (Sandbox Code Playgroud)

或者像这样:

find . -exec <command> {} \;
Run Code Online (Sandbox Code Playgroud)

如果不希望搜索不包含子目录,你可能需要添加的组合-type f,并-maxdepth 1以find命令.有关详细信息,请参见查找手册页.

  • 当目录中有10.000+个文件时,增加了不破坏的好处. (4认同)
  • 一直发生,比你想象的更频繁. (2认同)

pav*_*ium 8

这取决于您是否要在命令提示符下键入此命令,以及您要应用于文件的命令.

如果它是键入的,你可以选择你的第二个选择并用命令代替无害的东西.例如,我喜欢使用echo而不是mv或rm.

把它全部放在一行:

for i in * ; do command $i; done
Run Code Online (Sandbox Code Playgroud)

当它工作时 - 或者您可以看到它失败的地方,以及它是否无害,您可以按向上箭头,编辑命令并再试一次.


cra*_*ter 5

使用shopt防止扩展到*.txt

shopt -s nullglob
for myfile in *.txt
do
    # your code here
    echo $myfile

done
Run Code Online (Sandbox Code Playgroud)