Gul*_*Lim 5 bash whitespace for-loop find
好吧,我真的被困在这一个.
我有dirs.txt,如下:
/var/tmp/old files.txt
/var/tmp/old backups.bak
Run Code Online (Sandbox Code Playgroud)
dirs.txt文件由脚本本身生成.
当我想在for循环中使用dirs.txt时:
for dir in `cat dirs.txt` ; do
ls -al $dir
done
Run Code Online (Sandbox Code Playgroud)
这是命令抛出的内容:ls:无法访问/ var/tmp/old:没有这样的文件或目录
我希望整个文件名是ls -al'ed但它试图ls -al/var/tmp/old
我怎么能从for循环纠正这个?
Joh*_*ica 12
cat dirs.txt | while read dir; do
ls -al "$dir"
done
Run Code Online (Sandbox Code Playgroud)
使用反引号运算符时,输出将在每个空白字符处拆分为标记.read另一方面,一次只读一行,而不是一次读一个单词.因此,看起来有点奇怪的解决方案是将文件传输到循环中,以便可以逐行读取.
您需要"$dir"在ls命令中引用,以便将整个文件名,空白和所有文件名视为单个参数.如果你不这样做,ls将会看到两个文件名,/var/tmp/old和files.txt.
我可能会获得无用的猫奖.您可以通过删除以下内容进一步简化此操作cat:
while read dir; do
ls -al "$dir"
done < dirs.txt
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为整个 while循环就像一个大命令,所以就像你可以管道cat它,你也可以使用文件重定向.
根据dirs.txt生成方式的不同,您可以完全摆脱它并在一个命令中执行所有操作.如果它只是一个临时文件,您可以通过将命令生成直接传递dirs.txt到while循环中来跳过临时文件来消除它.例如,替换
find /var -name '*old*' > dirs.txt
while read dir; do
ls -al "$dir"
done < dirs.txt
Run Code Online (Sandbox Code Playgroud)
同
find /var -name '*old*' | while read dir; do
ls -al "$dir"
done
Run Code Online (Sandbox Code Playgroud)
假装find是您为生成文件列表而执行的任何命令.
实际上,如果你实际上在使用,find你可以在一个大find命令中做任何事情,没有任何循环或任何东西!例如,上面的代码使用find和while可以用这样的单个find命令完成:
find /var -name '*old*' -exec ls -al {} \;
Run Code Online (Sandbox Code Playgroud)
find是一个非常灵活的命令,可以搜索匹配各种复杂条件的文件,并使用该-exec选项将这些文件作为命令行参数传递给其他命令.当您使用-exec的{}获取与每个文件名替换.