【问题标题】:List files in the path列出路径中的文件
【发布时间】:2012-03-03 18:30:46
【问题描述】:

我有一个函数,它的第一个参数是存储到某个目录的路径的字符串。 该字符串是 find 的输出。 -type d.

如果我列出当前目录中的所有文件,它很简单

for file in *; do
  commands
done

但是对于字符串,它当然不会那样对待它。

for file in "$1"; do
  commands
done  

所以我想用 ls

for file in `ls "$1"`; do
  commands
done`

但是有了这个解决方案,它根本无法处理有空间的文件,经过一段时间 研究我到处都发现了使用 find 的建议,但我不明白,find 会 列出所有文件/目录/子目录,只是整个树,但我只想要当前目录中的东西。 我将非常感谢您的每一次帮助。

更新

我又尝试了一件似乎有效的方法:

pushd "$1"
for file in *; do
    echo "$file"
done
popd 

但我更喜欢一些不需要更改工作目录的解决方案

【问题讨论】:

  • 现在你知道为什么传统上 Unix 不鼓励在文件名中使用空格(尽管它一直允许它们)。当路径名中没有空格(换行符、退格符、制表符和其他控制字符)时,这些工具可以发挥最佳效果。
  • 使用:( cd "$1" || exit 1; ...),因为如果出现问题,这不会让您的主进程滞留在远程目录中。

标签: bash path


【解决方案1】:

如果您只想要非点文件,以下应该可以解决问题。

for file in "$1"/*; do
  commands
done  

更灵活的是下面的代码。

while IFS= read -r -d $'\0' result; do
    commands
done < <( find -P "$1" -printf %p"\0" )

【讨论】:

  • 我想非点文件不是隐藏文件,所以第一个例子应该可以解决问题,谢谢:)
【解决方案2】:

echo "$str" | while read file ; do echo $file; done

【讨论】:

    【解决方案3】:

    我相信您阅读的建议是使用 find 的-exec 功能。您可以传递命令来查找将为找到的每个文件执行的命令。

    $ find . -type d -exec stat {} \;
    

    首先,注意字符{}会被替换为文件名,你需要对分号\;进行转义。

    另外,这里还有另一个常见的 Bash 习惯用法,可以帮助您处理文件中的空格:

    $ find . -type d | 
    while read line; do
        # commands with $line
    done;
    

    【讨论】:

      【解决方案4】:

      已经有正确答案了,这更多的是作为奖励。当我遇到这个问题时,我通过“查找”打印文件名并将它们保存到文件中来解决它。之后,我逐行从文件中提取文件名。此外,可以使用来自文件的数据输入数据执行许多 shell 命令。

      【讨论】:

        【解决方案5】:

        如果你能管理它,这将是有效的:

        (
        cd "$1" || exit 1
        for file in *
        do
            commands
        done
        )
        

        括号在子外壳中运行内容。子外壳将目录更改为命名目录;然后 shell 的 globbing 处理文件名,包括带有空格的文件名。主要的警告是,如果您正在执行名称相对于 shell 启动的当前目录的命令,cd 操作会破坏一切。我的建议是“不要执行不在你的 PATH 上的命令”,在这种情况下,这不是问题。

        否则,请查看 bash 的数组和元字符扩展为数组。他们可以处理任务。

        注意find ... -print0,通常加上xargs -0 可以提供帮助。

        你也可以考虑:

        find "$1" -type f -maxdepth 1 -exec command {} +
        

        这将文件名作为正确的参数提供给command+ 表示法意味着“在命令行上方便地容纳尽可能多的文件名”。这与xargs 相比具有额外的优点,即在未找到文件时不执行命令,以及标准xargs 的令人恼火的设计(错误)功能(当然,GNU xargs 可以选择覆盖标准行为) .

        【讨论】:

        • 感谢您的建议,所以在子 shell 中运行内容比我提到的 pushd/popd 解决方案更好?我还需要根据当前处理的目录中的文件/文件夹返回不同的退出代码,所以在这种情况下我应该使用导出或类似的东西吗?目前,我正在考虑该主题中提到的所有可能方式,所以我想知道是否是更改此处提到的目录或列出整个路径并按照 Raz 发布的那样使用它的最佳解决方案
        • 我觉得 Raz 的解决方案很好很简单;我不知道为什么我自己不建议这样做。如果您打算使用cd,子外壳往往会很好;如果你的 shell 不能回到它开始的地方,这是很尴尬的(这可能会发生,尽管权限需要很奇怪)。但是,它们使状态处理变得复杂;您需要以适当的状态退出子 shell,然后在父 shell (estatus=$?) 中捕获它并决定如何处理它。捕捉很重要;如果你执行一个命令,$? 中的状态将会改变。选择 Raz 的解决方案;我已经投票了。
        猜你喜欢
        • 2017-10-22
        • 1970-01-01
        • 2021-12-11
        • 1970-01-01
        • 1970-01-01
        • 2021-05-02
        • 1970-01-01
        • 2021-05-22
        • 1970-01-01
        相关资源
        最近更新 更多