使用awk根据条件比较两个文件

问题描述 投票:0回答:1

我有两个文件:

1.TXT:

j_e_s_s_i_c_a_a_n_n [email protected]  61b8a203438ea1c56c1489ec7bea7a0e
9871951 [email protected] 671cb9239bf797a082f723a07a9c713f
holliebrian [email protected] a2e531ea7df55290c35d74082f38f020
9075407 [email protected]  d20f83ee6933aa1ea047fe5cbd9c1fd5
9837056 [email protected] e4d11b1c62cfbb7bfb49e4644e70d476

2.txt:

a2e531ea7df55290c35d74082f38f020:182:@*/
671cb9239bf797a082f723a07a9c713f:1199
e4d11b1c62cfbb7bfb49e4644e70d476:abcd123
d20f83ee6933aa1ea047fe5cbd9c1fd5:33;1:11

我希望这两个文件作为输出:一个是left.txt,其中1.txt的行将在那里,其第三列(FS ='')与第二列2.txt(FS =':')不匹配

left.txt:

j_e_s_s_i_c_a_a_n_n [email protected]  61b8a203438ea1c56c1489ec7bea7a0e

另一个文件是result.txt,其中1.txt中的所有行都包含2.txt中的匹配项。但是在输出文件中,匹配的第3列应该被匹配的第2列替换(FS =':')

的Result.txt:

9871951 [email protected] 1199
holliebrian [email protected] 182:@*/
9075407 [email protected] 33;1:11
9837056 [email protected] abcd123

我写了一个脚本来完成同样的任务:

awk -F : 'FNR==NR {s=$0;sub(/[^:]*:/, "", s); p[$1]=s; next} !($NF in p) {print > "left.txt"; next} {$NF=p[$NF]} 1' 2.txt FS=' ' OFS=' ' <(tr -d '\r' < 1.txt) > result.txt

我得到了预期的输出,但在更大的文件1.txt(~3GB)和2.txt(~1 GB)。该脚本崩溃,出现以下错误:

awk:cmd。 line:1:(FILENAME = 2.txt FNR = 21085923)致命:/home/corinna/src/gawk/gawk-4.2.0/gawk-4.2.0-1.x86_64/src/gawk-4.2.0/node .c:1021:more_blocks:freep:无法分配9600字节的内存(无法分配内存)

请帮我让脚本运行更大的文件。任何帮助将受到高度赞赏。使用awk不是必须的。唯一的座右铭是在较短的时间内完成正确的工作而不会崩溃。

linux bash awk
1个回答
2
投票

以下awk可能会帮助你。

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
© www.soinside.com 2019 - 2024. All rights reserved.