假设制表符分隔的文件作为输入文件 1 (
$IN1
):
$ cat input1.tsv
HEAD1 HEAD2 HEAD3 HEAD4 HEAD5 HEAD6
Qux ZX_999876 Bar Foo MN111111 Quux
Foo AB_123456 Bar Baz CD789123 Qux
Bar AC_456321 Baz Qux GF333444 Foo
Foo CD789123 Qux Baz GH987124 Qux
进一步假设一个 csv 分隔的文件作为输入文件 2 (
$IN2
):
$ cat input2.csv
AB_123456,CD789123
ZX_999876,MN111111
输入文件2指定需要删除输入文件1的哪些行。具体来说,如果输入文件 2 的第 1 列条目等于输入文件 1 的第 2 列条目,则输入文件 1 中输入文件 2 的第 2 列条目等于输入文件 1 的第 2 列条目的所有行为将被删除。
所需输出:
$ cat input1_filtered.tsv
HEAD1 HEAD2 HEAD3 HEAD4 HEAD5 HEAD6
Qux ZX_999876 Bar Foo MN111111 Quux
Foo AB_123456 Bar Baz CD789123 Qux
Bar AC_456321 Baz Qux GF333444 Foo
我希望通过 Bash 实现所需的输出。 我的(到目前为止还不够)尝试:
while IFS=, read -r CL1 CL2
do
if awk -F"\t" '$2=="$CL1"' $IN1
then
grep -vPw "(?<=\t)$CL2" $IN1 > tmp.txt
mv tmp.txt $IN1
fi
done < $IN2
这专门使用了 GNU awk:
gawk '
BEGINFILE { FS = ARGIND == 1 ? "," : "\t" }
ARGIND == 1 { is_present[$1] = $2; next }
ARGIND == 2 { if ($2 in is_present) del[is_present[$2]] = 1; next }
!($2 in del)
' input2.csv input1.tsv input1.tsv
输出
HEAD1 HEAD2 HEAD3 HEAD4 HEAD5 HEAD6
Qux ZX_999876 Bar Foo MN111111 Quux
Foo AB_123456 Bar Baz CD789123 Qux
Bar AC_456321 Baz Qux GF333444 Foo