【问题标题】:Shell Script to list files in a given directory and if they are files or directories用于列出给定目录中的文件以及它们是文件还是目录的 Shell 脚本
【发布时间】:2016-08-01 09:33:55
【问题描述】:

目前正在学习一些 bash 脚本,但遇到一个问题,涉及列出给定目录中的所有文件并说明它们是文件还是目录。我遇到的问题是我只能得到我当前的目录,或者如果指定一个目录,它只会说它是一个目录,例如。 /home/user/shell_scripts 将返回 shell_scipts 是一个目录,而不是其中包含的文件。 这是我目前所拥有的:

dir=$dir
for file in $dir; do
    if [[ -d $file ]]; then
        echo "$file is a directory"
    if [[ -f $file ]]; then
        echo "$file is a regular file"
    fi
done

【问题讨论】:

标签: bash shell


【解决方案1】:
ls -F ~ | \
sed 's#.*/$#/& is a Directory#;t quit;s#.*#/& is a File#;:quit;s/[*/=>@|] / /'

如果文件是目录,-F“分类”开关会附加一个“/”。 sed 代码打印所需的消息,然后删除后缀。

【讨论】:

  • 这不适用于名称中包含换行符的文件。
  • 谢谢@Biffen,这太可怕了,带有换行符的文件名是东西?现在才查到他们。刚做了一个。刚刚测试了上面的 sed 代码——它失败了。好的,但是谁甚至 想要 换行符,这东西的历史是什么?我得到了“如何”,并寻求“为什么”......
  • 我无法真正回答“为什么?”,除了“为什么不?”。 ;)
【解决方案2】:

如果您想列出也以 .使用:

for file in "${dir}/"* "${dir}/"/.[!.]* "${dir}/"/..?* ; do

【讨论】:

    【解决方案3】:

    您的线路:

    for file in $dir; do
    

    $dir 扩展为单个目录字符串。您需要做的是将其扩展为目录中的文件列表。您可以使用以下方法执行此操作:

    for file in "${dir}/"* ; do
    

    这会将"${dir}/"* 部分展开为当前目录的仅名称列表。正如 Biffen 指出的那样,如果其中任何一个包含空格,这应该保证文件列表不会以 file 中的拆分部分文件名结束。

    如果你想递归到dir 中的目录,那么使用find 可能是更好的方法。只需使用:

    for file in $( find ${dir} ); do
    

    请注意,虽然很简单,但它不会处理包含空格的文件或目录。因此,我很想放弃循环并一次性生成输出。这可能与您想要的略有不同,但可能更易于阅读且效率更高,尤其是对于大量文件。例如,列出所有目录:

    find ${dir} -maxdepth 1 -type d
    

    并列出文件:

    find ${dir} -maxdepth 1 -type f
    

    如果你想迭代到下面的目录,然后删除-maxdepth 1

    【讨论】:

    • 如果文件真的很多(命令行太长),这可能会中断。
    • 是的,它可能虽然我已经多次使用这种方法处理大量文件(> 10 ^ 5)并且没有遇到问题。如果可能的话,我很想放弃for/do/done 方法并直接使用lsfind 命令,这会更有效 - 尽管我试图保持在OP的问题。我会相应地更新。
    • 这不适用于包含空格或其他特殊字符的文件名。
    • 当然,我同意for 示例不会。我已经更改了第一个以更好地工作。不过,直接的find 示例应该可以正常工作。当然,这完全取决于输出将用于什么。一般来说,我发现有 101 个地方的文件名称中包含空格或其他特殊字符会导致问题,因此我会尽可能坚持更改它们
    【解决方案4】:

    这是globbing的好用处:

    for file in "$dir/"*
    do
      [[ -d "$file" ]] && echo "$file is a directory"
      [[ -f "$file" ]] && echo "$file is a regular file"
    done
    

    即使$dir 中的文件名称中包含特殊字符(例如空格、星号甚至换行符),这也将起作用。

    还要注意变量应该被引用 ("$file")。但* 不得被引用。我删除了dir=$dir,因为它什么都不做(除了当$dir 包含特殊字符时中断)。

    【讨论】:

      【解决方案5】:
      for file in $(ls $dir)
      do
          [ -f $file ] && echo "$file is File"
          [ -d $file ] && echo "$file is Directory"
      done
      

      或替换

      $(ls $dir)
      

      `ls $`
      

      【讨论】:

      • 这不适用于包含空格或其他特殊字符的文件名。 ls $ 应该做什么?!
      猜你喜欢
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多