好吧,我真的被困在这个。
我有dirs.txt,如下:
/var/tmp/old files.txt
/var/tmp/old backups.bak
dirs.txt文件由脚本本身生成。
当我想在for循环中使用dirs.txt时:
for dir in `cat dirs.txt` ; do
ls -al $dir
done
这是命令抛出的内容: ls:无法访问/ var / tmp / old:没有这样的文件或目录
我希望整个文件名都是ls -al'ed但是它会尝试ls -al / var / tmp / old
我如何从for循环中纠正这个问题?
答案 0 :(得分:12)
cat dirs.txt | while read dir; do
ls -al "$dir"
done
使用反引号运算符时,输出会在每个空格字符处拆分为标记。另一方面,read
将一次读取一行而不是一次读取一个单词。因此,看起来有点奇怪的解决方案是将文件传输到循环中,以便逐行读取。
您需要在"$dir"
命令中引用ls
,以便将整个文件名,空白和所有文件名视为单个参数。如果您不这样做,ls
会看到两个文件名,/var/tmp/old
和files.txt
。
我可能会获得Useless Use of Cat Award奖励。您可以通过删除cat
:
while read dir; do
ls -al "$dir"
done < dirs.txt
这是有效的,因为整个 while
循环就像一个大命令,所以就像你可以将cat
传递给它一样,你也可以使用文件重定向。
根据dirs.txt
的生成方式,您可能只能完全摆脱它并在一个命令中执行所有操作。如果它只是一个临时文件,你可以通过将命令生成dirs.txt
直接导入while
循环,跳过临时文件来消除它。例如,替换
find /var -name '*old*' > dirs.txt
while read dir; do
ls -al "$dir"
done < dirs.txt
与
find /var -name '*old*' | while read dir; do
ls -al "$dir"
done
假装find
是您为生成文件列表而执行的任何命令。
实际上,如果你实际上正在使用find
,你可以在一个大的find
命令中做任何事情而不需要任何循环或任何东西!例如,使用find
和while
的上述代码可以使用单个find
命令完成,如下所示:
find /var -name '*old*' -exec ls -al {} \;
find
是一个非常灵活的命令,可以搜索匹配各种复杂条件的文件,并使用-exec
选项将这些文件作为命令行参数传递给其他命令。当您使用-exec
时,{}
会被每个文件名替换。
答案 1 :(得分:0)
当我尝试解压缩目录中的大量文件时,我遇到了类似的问题。我发现因为我的“ls”别名,所以我自己造成了不必要的悲伤。一旦我将“ls”完全限定为“/ bin / ls”,一切都与世界相得益彰。
至于你的具体问题,我不清楚为什么你想要一个目录名后面的文件,你可能想要它们之间的斜杠(即/var/tmp/old/files.txt)。 / p>
然而,你想做“ls -al”的事实也不合适。您最终会做的是很多“ls -al / var / tmp / old”(每个dirs.txt条目一个),然后是每个本地文件的长列表,如你已经展示了files.txt和backups.bak。
然而,由于这个帖子将近2年,我想你已经很久没遇到这个问题:)