多个文件 - awk 命令过滤器

多个文件 - awk 命令过滤器

我用一个脚本说; filter1.sh 包含 awk 命令;

bzip2 -dc File_1.tsv.bz2 | awk -F '\t' 'BEGIN {OFS=FS} { if (($7) > 50)  print $0 }'  > File_1.tsv

bzip2 -dc File_2.tsv.bz2 | awk -F '\t' 'BEGIN {OFS=FS} { if (($7) > 50)  print $0 }'  > File_2.tsv

打开 bz2 文件并过滤第 7 列中大于 50 的值,并将输出写入新的 tsv 文件。

我有多个文件(大约 200 个,位于不同的目录中),我必须对其执行此过滤步骤(注意完全相同但相似)。

我的问题是如何为此目的传递多个文件,是否可以通过单独的 INFILE 传递文件(就像在 python 中一样)。

就像是;

./filter1.sh pathtofiles.in

在命令行中。其中 pathtofiles.in 包含文件的位置。

/home/users/gray_wolf/unix/File_1.tsv.bz2
/home/users/gray_wolf/unix/File_2.tsv.bz2
.
.
.
.
.

等等。

提前致谢。 〜M

答案1

您可以将它们全部放在一个输出流中,例如:

bzip2 -dc ./File_*.bz2 | filter

要将它们写到输出上的单独文件中,您需要以某种方式分隔流。如果您可以安排的话,这将是理想的解决方案 - 并且通过更多信息,您可以获得这样做的帮助。

否则,您可以为每个输入文件单独调用一次过滤器:

for j in ./File_*.bz2
do    [ -f "$j" ] &&
      bzip2 -dc "$j" |
      awk ... >"${j%.*}"
done

这并不理想,因为您必须为每个文件调用管道的新实例,但这对您来说可能是一个实用的解决方案。

要在另一个脚本文件中获取这样的for循环,然后向其传递您希望它使用的参数,您可以执行以下操作:

#!/bin/sh
for j do
      case $j in
      (*.bz2) [ -f "$j" ] &&
              bzip2 -dc --  "$j" |
              awk ...   >"${j.*}"
      esac
done

...这只是稍微复杂一点,以便它可以确保其所有参数都明确命名为扩展名,*.bz2以避免任何讨厌的事情,因为可能会传递没有扩展名的参数。,如果写入名为的可执行文件./script在具有 POSIX 的系统上/bin/sh,它可以被称为......

./script ./File_*.bz2

答案2

尝试

while read f
do
    bzip2 -dc "$f" | 
    awk -F '\t' 'BEGIN{OFS=FS} $7 > 50' > "$(basename "$f" .bz2)"
done < list-of-file.txt
  1. awk 会将结果从 File_1.tsv.bz2 写入 File_1.tsv,依此类推,写入 File_2、... File_960。
  2. 你给出的文件列表list-of-file.txt
  3. > $(basename $f .bz2)将在本地目录中创建结果

答案3

在 bash 中,您可以尝试以下操作:

for f in `cat $1`
do
  bzip ...
done

这可能不适用于所有 shell,毫无疑问还有其他方法可以实现这一点。$1意思是“传递给脚本的第一个参数”。

答案4

#!/bin/bash
while read -r j
do 
    [ -f "$j" ] && 
    bzip2 -dc "$j" |
    sed -r '/^([^\t]+\t){6}0*([1-9][0-9]{2,}|[6-9][0-9]|5[1-9])/! d' > "${j%.*}"
done <"$1"

相关内容