我用一个脚本说; 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
- awk 会将结果从 File_1.tsv.bz2 写入 File_1.tsv,依此类推,写入 File_2、... File_960。
- 你给出的文件列表
list-of-file.txt
> $(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"