【问题标题】:Reading files in order in BASH script在 BASH 脚本中按顺序读取文件
【发布时间】:2011-06-28 04:32:48
【问题描述】:

所以我有一个 bash 脚本,它 greps 一系列子目录,查找包含特定字符串的文件,然后打印文件总数和目录总数以查找字符串的出现。代码如下。

  for dir in $(find * -type d); do
  echo "directory: $dir" >> $OUT
  for f in $(find $dir/* -type f); do
    echo -n "$(basename $f) " >> $OUT
    grep -c -h $1 $f >> $OUT
  done
  echo -n "directory total: " >> $OUT
  grep -c -h $1 $dir/*.* | awk '{SUM += $1} END {print SUM}' >> $OUT
  done

当它这样做时,如果我读入 10 个文件,它会在文本文件中将它们列为 file1.txt、file10.txt、file2.txt 等...

有什么方法可以让它打印 file1.txt、file2.txt、file3.txt 等,并让第 10 个文件按顺序列出?

我是 BASH 的新手,所以我想知道是否有人对此有所了解。非常感谢任何帮助。是的,这些文件的字面意思是 file1.txt、file2.txt 等。这主要是为了让自己熟悉 BASH 脚本。

【问题讨论】:

  • 出于这个原因,我通常将文件命名为file01.txtfile02.txt、...file99.txt

标签: bash sorting file grep


【解决方案1】:

文件按字典顺序排序(这就是为什么 file10 排在 file1 之后)。如果文件被命名为file<num>,那就更简单了——你可以在它们上使用sort -k1.5n。在一般情况下,它会比较棘手 - 会涉及一些解析,请判断您的情况是否一般:)

几点:

您可能不需要find $dir/* -type f,而是find $dir -type f。在前一种情况下,您使用 shell 的 globbing 功能。子目录呢?

顺便说一句,您可以将其重写如下以跳过使用>> $OUT 的每一行垃圾邮件:

for dir in $(find * -type d); do
  echo "directory: $dir"
  for f in $(find $dir/* -type f); do
    echo -n "$(basename $f) "
    grep -c -h $1 $f
  done
  echo -n "directory total: "
  grep -c -h $1 $dir/*.* | awk '{SUM += $1} END {print SUM}'
done >> $OUT

【讨论】:

    【解决方案2】:

    改变这一行:

    for f in $(find $dir/* -type f); do
    

    到这一行:

    for f in $(find $dir/* -type f | sort --numeric-sort); do
    

    【讨论】:

    • 我相信数字排序不会有帮助,因为键的开头不是数字。
    【解决方案3】:

    所以我想我是在你们的帮助和一些修补下弄明白的。不确定这是否是最好的方法,但我最终完成了这项工作......

    for f in $(find $dir -type f | cut -d. -f1 | cut -d'e' -f3 | sort -n); do
        echo -n "  file$(basename $f).txt: "
        grep -c -h $1 $dir/"file$f"'.txt'
      done
    

    显然,这对我拥有的文件名非常具体,但了解更多信息是件好事。谢谢

    【讨论】:

      【解决方案4】:
      find -type d | while read -r dir
      do
          echo "directory: $dir"
          find "$dir" -maxdepth 1 -type f | sort --version-sort | while read -r f
          do
              echo -n "$(basename "$f") "
              grep -c -h "$1" "$f"
          done
          grep -c -h "$1" "$dir/*" | awk -F: '{SUM += $1} END {print "directory total:", SUM}'
      done > "$OUT"
      
      • 将重定向移动到循环的末尾
      • 如果文件名包含空格,请使用 while read 而不是 for(如果需要,可以采取其他措施来防止一些不太常见的奇数字符)
      • 引用变量也可以保护空白
      • 使用-maxdepth 1 和内部find 以避免重叠重复
      • 使用sort --version-sort 按您想要的顺序获取文件名
      • AWK 可以在打印总数的同时打印文本
      • 字段分隔符需要设置为冒号
      • 您可以使用echo -n "${f##*/} " 而不是echo -n "$(basename "$f") "

      【讨论】:

        猜你喜欢
        • 2014-10-26
        • 1970-01-01
        • 2019-08-03
        • 1970-01-01
        • 2022-05-30
        • 1970-01-01
        • 1970-01-01
        • 2022-09-06
        • 1970-01-01
        相关资源
        最近更新 更多