【问题标题】:Matching files using awk in linux在 linux 中使用 awk 匹配文件
【发布时间】:2018-01-04 18:00:42
【问题描述】:

我有 2 个文件:

1.txt:

e10adc3949ba59abbe56e057f20f883e
f8b46e989c5794eec4e268605b63eb59
e3ceb5881a0a1fdaad01296d7554868d

2.txt:

e10adc3949ba59abbe56e057f20f883e:1111
679ab793796da4cbd0dda3d0daf74ec1:1234
f8b46e989c5794eec4e268605b63eb59:1@/233:

我想要 2 个文件作为输出: 一个是 result.txt,其中包含来自 2.txt 的行,其匹配在 1.txt 另一个是 left.txt,其中包含 1.txt 中匹配不在 2.txt 中的行

两个文件的预期输出如下: 结果.txt

e10adc3949ba59abbe56e057f20f883e:1111
f8b46e989c5794eec4e268605b63eb59:1@/233:

left.txt

e3ceb5881a0a1fdaad01296d7554868d

我用 awk 尝试了 1-2 种方法,但没有成功。任何帮助将不胜感激。

我的脚本:

awk '
FNR==NR{
  val=$1;
  sub(/[^:]*/,"");
  sub(/:/,"");
  a[val]=$0;
  next
}
!($NF in a){
  print > "left.txt";
  next
}
{
  print $1,$2,a[$NF]> "result.txt"
}
'  FS=":" 2.txt FS=":"  OFS=":" 1.txt

【问题讨论】:

  • 目标是您添加一些自己的代码,以至少展示您为解决这个问题所做的研究工作。
  • 有了你最后两个问题(Merge two files using awk in linuxCompare two files based on the condition using awk)的答案,你应该可以自己做。
  • 我已经删除了我的帖子(该帖子发布在赛勒斯评论时间副附近),请回答赛勒斯问题将重新发布。
  • 我试图从我最近的 2 个帖子中学习,但脚本非常复杂,所以我无法理解它们。我现在发布了这个简单的问题,以便我可以从中学习。谢谢:)
  • @BhawandeepSingla,很公平,我现在在我的答案中添加了解释,请尝试从它和其他答案中学习,因为我们都在这里改进和学习,干杯:)

标签: linux bash awk


【解决方案1】:

关注awk 可能对您有所帮助。

awk 'FNR==NR{a[$1]=$0;next} ($0 in a){print a[$0] > "results.txt";next} {print > "left.txt"}' FS=":" OFS=":" 2.txt FS=" " OFS=":" 1.txt

编辑:在这里也添加代码解释。

awk '
FNR==NR{    ##FNR==NR condition will be TRUE when first Input_file is being read by awk. Where FNR and NR are the out of the box variables for awk.
  a[$1]=$0; ##creating an array named a whose index is $1 and value is $2 from 2.txt Input_file.
  next      ##next is out of the box keyword from awk and will skip all further statements of awk.
}
($0 in a){  ##Checking here condition if current line of Input_file 1.txt is present in array named a then do following.
  print a[$0] > "results.txt"; ##Printing the current line into output file named results.txt, since current line is coming in array named a(which was created by 1st file).
  next      ##next is awk keyword which will skip further statements for awk code now.
}
{
  print > "left.txt" ##Printing all lines which skip above condition(which means they did not come into array a) to output file named left.txt as per OP need.
}
' FS=":" OFS=":" 2.txt FS=" " OFS=":" 1.txt ##Setting FS(field separator) as colon for 2.txt and Setting FS to space for 1.txt here. yes, we could set multiple field separators for different Input_file(s).

【讨论】:

  • 感谢您的帮助 :) 但是您的 results.txt 输出与我的 result.txt 输出不匹配
  • e10adc3949ba59abbe56e057f20f883e 1111 f8b46e989c5794eec4e268605b63eb59 1@/233 仍然不匹配所需的输出。 left.txt 是完美的。
  • 感谢您的详细解释。我自己也解决了另外两个问题。现在我完全理解了这个概念。
  • @BhawandeepSingla,很高兴它对您有所帮助。继续分享,继续学习,加油:)
  • 该脚本不适用于较大的文件,例如 3 GB 文件。 :(
【解决方案2】:

这个怎么样:

awk 'BEGIN{ FS = ":" }NR==FNR{ a[$0]; next }$1 in a{ print $0 > "results.txt"; delete a[$1]; next }END{ for ( i in a ) print i > "left.txt" }' 1.txt 2.txt

输出:

结果.txt

e10adc3949ba59abbe56e057f20f883e:1111
f8b46e989c5794eec4e268605b63eb59:1@/233:

left.txt

e3ceb5881a0a1fdaad01296d7554868d

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    相关资源
    最近更新 更多