在bash中迭代几个文件

时间:2016-10-20 11:19:51

标签: bash

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

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&# 39;而不只是' 1')。

非常感谢

5 个答案:

答案 0 :(得分:1)

bash中范围的语法是

{1..150}

不是{1:150}

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

{001..150}

for循环的正确语法需要dodone

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

目前还不清楚脚本中包含的$1

答案 1 :(得分:1)

迭代文件我相信更简单的方法是: (假设目录中没有名为' file。*。txt'的文件,并且您的输出文件可以有不同的名称)

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

答案 2 :(得分:1)

使用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变量前端的输出参见Manipulating Strings

答案 3 :(得分:0)

尝试 -

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

答案 4 :(得分:0)

范围的语法是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