【问题标题】:Iterate through several files in bash [duplicate]遍历bash中的几个文件[重复]
【发布时间】:2017-03-02 08:50:16
【问题描述】:

我有一个文件夹,其中包含多个文件,这些文件的名称如下:

file.001.txt.gz, file.002.txt.gz, ... , file.150.txt.gz

我想要做的是使用循环来运行每个文件的程序。我在想这样的事情(只是一个草图):

for i in {1:150}
  gunzip file.$i.txt.gz
  ./my_program file.$i.txt output.$1.txt
  gzip file.$1.txt

首先,我不知道这样的事情是否可行,其次,我不知道如何保留文件的三位数字('001' 而不是'1') .

非常感谢

【问题讨论】:

  • 第一步,您需要将 'output.$1.txt' 更改为 'output.$i.txt'

标签: bash


【解决方案1】:

bash 中范围的语法是

{1..150}

不是{1:150}

此外,如果您的 bash 足够新,您可以添加前导零:

{001..150}

for循环的正确语法需要dodone

for i in {001..150} ; do
    # ...
done

不清楚$1 在您的脚本中包含什么。

【讨论】:

    【解决方案2】:

    要遍历文件,我认为更简单的方法是: (假设目录中已经没有名为 'file.*.txt' 的文件,并且您的输出文件可以有不同的名称)

    for i in file.*.txt.gz; do
        gunzip $i
        ./my_program $i $i-output.txt
        gzip file.*.txt
    done
    

    【讨论】:

      【解决方案3】:

      使用find 命令:

      # Path to the source directory
      dir="./"
      
      while read file
      do
        output="$(basename "$file")"
        output="$(dirname "$file")/"${output/#file/output}
        echo "$file ==> $output"
      done < <(find "$dir" \
        -regextype 'posix-egrep' \
        -regex '.*file\.[0-9]{3}\.txt\.gz$')
      

      同样的通过管道:

      find "$dir" \
        -regextype 'posix-egrep' \
        -regex '.*file\.[0-9]{3}\.txt\.gz$' | \
        while read file
        do
          output="$(basename "$file")"
          output="$(dirname "$file")/"${output/#file/output}
          echo "$file ==> $output"
        done
      

      样本输出

      /home/ruslan/tmp/file.001.txt.gz ==> /home/ruslan/tmp/output.001.txt.gz
      /home/ruslan/tmp/file.002.txt.gz ==> /home/ruslan/tmp/output.002.txt.gz
      

      (对于$dir=/home/ruslan/tmp/)。

      说明

      脚本迭代$dir 目录中的文件。 $file 变量由find 命令读取的下一行填充。 find 命令返回正则表达式'.*file\.[0-9]{3}\.txt\.gz$' 对应的路径列表。

      $output 变量由两部分组成:basename(没有目录的路径)和 dirname(文件目录的路径)。

      ${output/#file/output} 表达式将$output 变量前端的file 替换为output参见Manipulating Strings

      【讨论】:

        【解决方案4】:

        试试-

        for i in $(seq -w 1 150)     #-w adds the leading zeroes
        do
          gunzip file."$i".txt.gz
          ./my_program file."$i".txt output."$1".txt
          gzip file."$1".txt
        done
        

        【讨论】:

        • 虽然这段代码可能有助于解决问题,但它并没有解释为什么和/或如何回答问题。提供这种额外的背景将显着提高其长期教育价值。请edit您的答案添加解释,包括适用的限制和假设。
        【解决方案5】:

        范围的语法是as choroba said,但在迭代文件时,您通常希望使用 glob。如果您知道所有文件的名称中都包含三位数字,则可以在数字上进行匹配:

        shopt -s nullglob
        for i in file.0[0-9][0-9].txt.gz file.1[0-4][0-9] file.15[0].txt.gz; do
          gunzip file.$i.txt.gz
          ./my_program file.$i.txt output.$i.txt
          gzip file.$i.txt
        done
        

        这只会遍历存在的文件。如果使用范围表达式,则必须格外小心,不要尝试对不存在的文件进行操作。

        for i in file.{000..150}.txt.gz; do
            [[ -e "$i" ]] || continue
            ...otherstuff
        done
        

        【讨论】:

          猜你喜欢
          • 2013-04-23
          • 1970-01-01
          • 1970-01-01
          • 2021-01-16
          • 1970-01-01
          • 1970-01-01
          • 2011-12-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多