【问题标题】:compare two file and print the lines that have matching columns awk比较两个文件并打印具有匹配列的行 awk
【发布时间】:2022-02-05 11:12:48
【问题描述】:

如果一个文档的行与第二个文件的第一列匹配,我需要使用 AWK 打印它们。

第一个文件(comprobacio.txt):

2187405XJ4228N0001RX
42379999999997GH0002 
517878G4RSD407yJK4NY
4237405HHYT4323H0002
517P0P0P06GH9001233F
517878G4R67TRRHOPPNY
423123R66677789323H2

第二个文件(datos.txt):

2187405XJ4228N0001RX@1984@216@230 08m 06s N, 82o 21m 34s W 
4237405XJK4N37GH0002@2010@54@400 02m Ols N, 80o 20m 12s W 
517878G4RSO405XJK4NY@1954@103@400 42m 51s N, 74o 06m 21s E 
4237405HHYT4323H0002@2006@55@300 04m Ols N, 810 20m 12s W 
517POLIJ56GH9001233F@2010@803@400 52m 52s N, 74o 06m 70s E 
517878G4R67TRRHOPPNY@1954@108@400 42m 51s N, 74o 05m 21s E 
4237405899544T4323H2@2000@5778@390 12m 07s N, 900 10m 12s W 

预期输出

2187405XJ4228N0001RX@1984@216@230 08m 06s N, 82o 21m 34s W 
4237405HHYT4323H0002@2006@55@300 04m Ols N, 810 20m 12s W
517878G4R67TRRHOPPNY@1954@108@400 42m 51s N, 74o 05m 21s E

我尝试先用 sed 编辑第二个文件以消除“@”字符并将其替换为空格“”。然后用 AWK 管道输出具有相同第一列但不输出任何内容的行。

sed 's/@/ /g' datos.txt | awk 'FNR==NR{array[$1];next} $1 in array {print $0}' datos.txt comprobacio.txt

知道我做错了什么吗?

【问题讨论】:

  • 在使用 awk 时永远不需要 sed。

标签: bash awk


【解决方案1】:

试试这样:

awk -F '@' 'NR==FNR{a[$0];next} $1 in a' comprobacio.txt datos.txt 
2187405XJ4228N0001RX@1984@216@230 08m 06s N, 82o 21m 34s W 
4237405HHYT4323H0002@2006@55@300 04m Ols N, 810 20m 12s W 
517878G4R67TRRHOPPNY@1954@108@400 42m 51s N, 74o 05m 21s E

我们将 if 字段分隔符 FS 设置为带有 -F '@'@ 符号。

但是您的代码中的问题是您替换的同时从 STDIN 和文件中读取。要在 awk 中执行此操作,您需要将文件名设置为 - 以表示 STDIN,如下所示:

sed 's/@/ /g' datos.txt | awk 'FNR==NR{array[$1];next} $1 in array {print $0}' comprobacio.txt -
2187405XJ4228N0001RX 1984 216 230 08m 06s N, 82o 21m 34s W 
4237405HHYT4323H0002 2006 55 300 04m Ols N, 810 20m 12s W 
517878G4R67TRRHOPPNY 1954 108 400 42m 51s N, 74o 05m 21s E 

注意尾随的减号 (-)。

另一种选择是使用进程替换,例如:

awk 'FNR==NR{array[$1];next} $1 in array {print $0}' comprobacio.txt  <(sed 's/@/ /g' datos.txt)
2187405XJ4228N0001RX 1984 216 230 08m 06s N, 82o 21m 34s W 
4237405HHYT4323H0002 2006 55 300 04m Ols N, 810 20m 12s W 
517878G4R67TRRHOPPNY 1954 108 400 42m 51s N, 74o 05m 21s E 

请注意,在这种情况下,输出中的 @ 符号将替换为空格。

【讨论】:

  • 对不起,我已经纠正了错误,我写错了文件名
  • @Aleix:已更新以匹配更新后的问题。
  • @Aleix:还添加了一个如何同时从标准输入和文件中读取的示例。
【解决方案2】:

在这种情况下,您可以在已排序的文件上使用join

join -1 1 -2 1 -t @ <(sort file1) <(sort file2) 
2187405XJ4228N0001RX@1984@216@230 08m 06s N, 82o 21m 34s W 
4237405HHYT4323H0002@2006@55@300 04m Ols N, 810 20m 12s W 
517878G4R67TRRHOPPNY@1954@108@400 42m 51s N, 74o 05m 21s E 

【讨论】:

    【解决方案3】:

    像这样使用 grep:

    grep -Ff comprobacio.txt datos.txt
    

    grep 使用的选项:

       -F, --fixed-strings
              Interpret PATTERNS as fixed strings, not regular expressions.
    
       -f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  If this option is used
              multiple  times  or  is  combined with the -e (--regexp) option,
              search for all patterns given.  The  empty  file  contains  zero
              patterns, and therefore matches nothing.
    

    【讨论】:

    • 这很好,但不是完全等同于 OP 的代码,因为它将匹配文件 datos.txt 中的任何位置,而不仅仅是第一个字段。
    猜你喜欢
    • 2016-07-30
    • 2020-10-05
    • 2020-12-13
    • 2017-07-30
    • 1970-01-01
    • 2021-06-15
    • 2020-04-16
    • 2020-11-24
    • 2016-10-23
    相关资源
    最近更新 更多