我正在使用 bash shell。如果我有一个行号文件
1
4
7
9
和另一个行文件,其中第一个元素是数字,后跟文本字符串
1,Michael Jordan
2,Karl Malone,
3,Charles Barkley
4,Greg Anthony
5,Chris Mullen
6,Reggie Miller
7,Billy Owens
8,David Robinson
9,Shaquille O'Neal
10,John Stockton
awk
仅当第一个数字属于第一个文件时,如何编写命令以从第二个文件中提取行?在上面的例子中,我期望这个结果
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
我试过这个
awk 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file /tmp/second_file > /tmp/third_file
但它在第三个文件中什么也没产生。
答案1
由于您的第二个文件是逗号分隔的,因此您需要使用命令行选项将 awk 字段分隔符设置为,
- :-F
awk -F, 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file /tmp/second_file > /tmp/third_file
或通过FS
内置变量:
awk 'FNR==NR{a[$1];next} $1 in a' /tmp/first_file FS=, /tmp/second_file > /tmp/third_file
后一种方法将允许您处理第一个文件不是逗号分隔(并且有多个字段)的情况。
答案2
使用乐(以前称为 Perl_6)
~$ raku -ne 'BEGIN my @a = "nbr_list.txt".IO.lines.map: *.Int; \
.put if $_.split(",")[0] == any(@a);' file.csv
#OR
~$ raku -ne 'BEGIN my @a = "nbr_list.txt".IO.lines.map: *.Int; \
.put if $_.split(",")[0] ~~ any(@a);' file.csv
Raku 是 Perl 家族的一种编程语言。当您 时BEGIN
,获取数字列表并将其存储在数组中@a
。然后,标志-ne
从命令行读取文件,而不自动打印(awk
类似行为)。
此处,该行被读入主题变量 ( $_
)(位于逗号上),并获取split
第一个元素 ( )。使用数值相等运算符(第一个代码示例)或 Raku 的智能匹配运算符来[0]
比较这些元素。在操作员的右侧,阵列变成了结点。如果满足条件,则条件输出该行。==
~~
@a
any()
if
put
输入示例:
1,Michael Jordan
2,Karl Malone,
3,Charles Barkley
4,Greg Anthony
5,Chris Mullen
6,Reggie Miller
7,Billy Owens
8,David Robinson
9,Shaquille O'Neal
10,John Stockton
示例输出(使用nbr_list.txt
由 1,4,7,9 组成的文件):
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
连接点很有趣,因为它们会自动线程化。对于上述问题,one()
连接器也可以工作,甚至可能更有效。
另一种方法是使用集合:将行号转换为 a Set
of Int
s。数据按行读取,每个第一列都被强制为Int
,并检查它是否是(elem)
集合的元素。请注意,以下代码中可以使用infix(elem)
或 infix , (Unicode 符号):∈
~$ raku -ne 'BEGIN my $set1 = Set.new("nbr_list.txt".IO.lines.map: *.Int); \
.put if $_.split(",").[0].Int (elem) $set1;' file
由于 Raku Sets 只能包含唯一值(即它们“唯一化”输入),因此第二个示例将丢弃文件中的重复项"nbr_list.txt"
。这确实可能是OP所希望的。
https://docs.raku.org/type/Junction
https://docs-stage.raku.org/type/Junction
https://raku.org
答案3
这种操作称为“连接”。 coreutils 中有一个工具用于join
连接文本文件。
join -t, -j1 --nocheck-order first_file second_file
1,Michael Jordan
4,Greg Anthony
7,Billy Owens
9,Shaquille O'Neal
解释:
-t,
- 使用逗号作为字段分隔符-j1
- 加入第一个字段--nocheck-order
- join 需要对文件进行排序,但它不喜欢数字排序。因此,我们阻止它检查字典排序并抱怨“9”前置“10”。只要两个文件中的第一列使用相同的算法排序,它仍然有效。