使用两个文件的Bash/AWK条件

首先,感谢您的帮助。我在尝试使用两个文件使用 bash 条件时遇到问题。我有文件letters.txt

A
B
C

我有文件 number.txt

B  10
D  20
A  15
C  18
E  23
A  12
B  14

我想使用条件,所以如果文件 letter.txt 中的一个字母也在 number.txt 中,它会生成文件 a.txt b.txt c.txt 所以看起来像这样:

一个.txt

A  12
A  15

b.txt

 B  10
 B  14

文件

C  18

我知道我可以使用以下代码做到这一点:

cat number.txt | awk '{if($1=="A")print $0}' > a.txt

但我想用两个文件来做。

回答

解决此类问题的有效方法是首先对关键字段上的输入进行排序,这样您就不需要同时打开多个输出文件(这有限制和/或会减慢管理它们的处理速度)或在读取每一行时打开/关闭输出文件(这总是很慢)。

使用 GNU sort for -s(stable sort) 保留非关键字段的输入顺序,一次只打开 1 个输出文件,并在填充的整个时间保持打开状态:

$ sort -k1,1 -s number.txt |
awk '
    NR==FNR { lets[$1]; next }
    !($1 in lets) { next }
    $1 != prev { close(out); out=tolower($1) ".txt"; prev=$1 }
    { print > out }
' letters.txt -

$ head ?.txt
==> a.txt <==
A  15
A  12

==> b.txt <==
B  10
B  14

==> c.txt <==
C  18

如果您没有 GNU sort for-s来保留每个关键字段的行的输入顺序,您可以将其替换为awk | sort | cut,例如:

$ sort -k1,1 -s number.txt
A  15
A  12
B  10
B  14
C  18
D  20
E  23
$ awk '{print NR, $0}' number.txt | sort -k2,2 -k1,1n | cut -d' ' -f2-
A  15
A  12
B  10
B  14
C  18
D  20
E  23

请注意A与输入顺序相比,第二个字段的顺序发生了变化而没有执行上述操作,因为默认情况下sort不保证保留其排序的每个键的相对行顺序:

$ sort -k1,1 number.txt
A  12
A  15
B  10
B  14
C  18
D  20
E  23


以上是使用两个文件的Bash/AWK条件的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>