Bash For循环使用find';t正确处理具有空格字符的目录名

Bash For循环使用find';t正确处理具有空格字符的目录名,bash,find,whitespace,for-loop,Bash,Find,Whitespace,For Loop,我真的被这件事难住了 我有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/va

我真的被这件事难住了

我有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循环中更正此问题

cat dirs.txt | while read dir; do
    ls -al "$dir"
done
  • 使用backtick运算符时,输出将在每个空白字符处拆分为标记<另一方面,code>read将一次读取一行,而不是一次读取一个单词。因此,解决方案看起来有点奇怪,就是将文件通过管道传输到循环中,以便逐行读取

  • 您需要在
    ls
    命令中引用
    “$dir”
    ,以便将整个文件名(空格和all)视为单个参数。如果不这样做,
    ls
    将看到两个文件名,
    /var/tmp/old
    files.txt

  • 我可能会被授予这个奖项。通过删除
    cat
    ,您可以进一步简化此操作:

    while read dir; do
        ls -al "$dir"
    done < dirs.txt
    

    假装
    find
    是生成文件列表所执行的任何命令

    实际上,如果您实际上使用的是
    find
    ,那么您可能可以在一个大的
    find
    命令中完成所有操作,而不需要任何循环或任何东西!例如,上述使用
    find
    while
    的代码可以通过如下单个
    find
    命令完成:

    find /var -name '*old*' -exec ls -al {} \;
    

    find
    是一个非常灵活的命令,它既可以搜索与各种复杂条件匹配的文件,也可以使用
    -exec
    选项将这些文件作为命令行参数传递给其他命令。当您使用
    -exec
    时,
    {}
    会被每个文件名替换。

    当我尝试解压缩目录中的许多文件时,我遇到了类似的问题。我发现,由于我的“ls”有别名,我给自己带来了不必要的悲伤。一旦我将“ls”完全限定为“/bin/ls”,整个世界都很好

    但是,对于您的具体问题,我不清楚为什么您希望在目录名之后有一个文件,而您可能希望在它们之间有一个斜杠(即/var/tmp/old/files.txt)

    然而,您想要执行“ls-al”的事实也不适合。您最终似乎要做的是大量的“ls-al/var/tmp/old”(每个dirs.txt条目一个),然后是每个本地文件的长列表,如您所示,这些文件名为files.txt和backups.bak


    然而,由于这个线程已经有将近2年的历史了,我想你早已解决了这个问题:)

    请注意,任何“somecommand | while read…”版本都有可能出现问题:while循环在子shell中运行,因此其中设置的任何变量在退出时都会消失。“while…done”和bash允许您避免临时文件:
    while read-r行;do…done<
    
    find /var -name '*old*' | while read dir; do
        ls -al "$dir"
    done
    
    find /var -name '*old*' -exec ls -al {} \;