【问题标题】:Is it possible to take 2 columns from File 1, find them in File 2 and extract the relevant lines from File 2 into File 3?是否可以从文件 1 中取出 2 列,在文件 2 中找到它们并将文件 2 中的相关行提取到文件 3 中?
【发布时间】:2019-04-23 11:36:32
【问题描述】:

我有 2 个文本文件。 File1 大约有 1,000 行,File2 有 20,000 行。 File1 的摘录如下:

 /BBC Micro/Thrust
 /Amiga/Alien Breed Special Edition '92
 /Arcade-Vertical/amidar
 /MAME (Advance)/mario
 /Arcade-Vertical/mspacman
 /Sharp X68000/Bubble Bobble (1989)(Dempa)
 /BBC Micro/Chuckie Egg

File2 的摘录如下:

 005;005;Arcade-Vertical;;;;;;;;;;;;;;
 Alien Breed Special Edition '92;Alien Breed Special Edition '92;Amiga;;1992;Team 17;Action / Shooter;;;;;;;;;;
 Alien 8 (Japan);Alien 8 (Japan);msx;;1987;Nippon Dexter Co., Ltd.;Action;1;;;;;;;;;
 amidar;amidar;Arcade-Vertical;;;;;;;;;;;;;;
 Bubble Bobble (Japan);Bubble Bobble (Japan);msx2;;;;;;;;;;;;;;
 Buffy the Vampire Slayer - Wrath of the Darkhul King (USA, Europe);Buffy the Vampire Slayer - Wrath of the Darkhul King (USA, Europe);Nintendo Game Boy Advance;;2003;THQ;Action;;;;;;;;;;
 mario;mario;FBA;;;;;;;;;;;;;;
 mspacman;mspacman;Arcade-Vertical;;;;;;;;;;;;;;
 Thrust;Thrust;BBC Micro;;;;;;;;;;;;;;
 Thunder Blade (1988)(U.S. Gold)[128K];Thunder Blade (1988)(U.S. Gold)[128K];ZX Spectrum;;;;;;;;;;;;;;
 Thunder Mario v0.1 (SMB1 Hack);Thunder Mario v0.1 (SMB1 Hack);Nintendo NES Hacks 2;;;;;;;;;;;;;;
 Thrust;Thrust;Vectrex;;;;;;;;;;;;;;

在 File3(输出文件)中,使用 grep、sed、awk 或 bash 脚本,我想实现以下输出:

  Thrust;Thrust;BBC Micro;;;;;;;;;;;;;;
  Alien Breed Special Edition '92;Alien Breed Special Edition '92;Amiga;;1992;Team 17;Action / Shooter;;;;;;;;;;
  amidar;amidar;Arcade-Vertical;;;;;;;;;;;;;;
  mspacman;mspacman;Arcade-Vertical;;;;;;;;;;;;;; 

这与我之前提出的问题相似,但不一样。我特别想避免 Thrust;Thrust;Vectrex;;;;;;;;;;;;;;记录在文件 3 中。

使用 sudo awk -F\; 'NR==FNR{a[$1]=$0;next}$1 in a{print a[$1]}',我发现 Thrust;Thrust;Vectrex;;;;;;;;;;;;;;被记录在文件 3 而不是 Thrust;Thrust;BBC Micro;;;;;;;;;;;;;;; (后者是我正在寻找的输出)。

同样,mario;mario;FBA;;;;;;;;;;;;;;;不会出现在 File3 中,因为它与 /MAME (Advance)/mario 不匹配,因为“MAME (Advance)”不匹配。那很好。 Bubble Bobble (日本);Bubble Bobble (日本);msx2;;;;;;;;;;;;;与“Sharp X68000”或“Bubble Bobble (1989)(Dempa)”都不匹配。

【问题讨论】:

  • 选线的标准一点都不清楚。使用; 作为FS,file1 的$1 是整行。请详细说明如何根据file1的内容从file2中选择行
  • 例如,如果文件 1 的第 1 列和第 2 列(例如 BBC Micro 和 Thrust)都在文件 2 的一行中(例如 Thrust;Thrust;BBC Micro;;;;; ;;;;),则该行 (Thrust;Thrust;BBC Micro;;;;;;;) 将记录在文件 3 中。文件 2 中的行是 Thrust;Thrust;Vectrex;;;;;;; ;不会记录在文件 3 中,因为它与 BBC Micro 不匹配。
  • 你是对的。对于那个很抱歉。我需要更改 File3 以反映正确的输出。
  • 看来您可以将file1中的“column 2”与file2中的第一个字段匹配,并将file2中的“column 1”与file2中的第三个字段匹配。这是你的匹配规则吗?或者,正如您所说,来自 file2 的数据只需“匹配”?
  • 谢谢,格伦。这是对我正在寻找的内容的正确总结。很抱歉问题不清楚。

标签: bash awk sed grep


【解决方案1】:

使用 AWK 和关联数组你可以这样使用:

awk '
BEGIN {
  if ( ARGC != 3 ) exit(1);
  FS="/";
  while ( getline < ARGV[2] ) mfggames[$2"/"$3]=1;
  FS=";";
  ARGC=2;
}
mfggames[$3"/"$1]
' file2 file1

输出:

Alien Breed Special Edition '92;Alien Breed Special Edition '92;Amiga;;1992;Team 17;Action / Shooter;;;;;;;;;;
amidar;amidar;Arcade-Vertical;;;;;;;;;;;;;;
mspacman;mspacman;Arcade-Vertical;;;;;;;;;;;;;;
Thrust;Thrust;BBC Micro;;;;;;;;;;;;;;

按 file1 解决方案排序(根据评论请求):

awk '
BEGIN {
  if ( ARGC != 3 ) exit(1);
  FS="/";
  while ( getline < ARGV[2] ) mfggames[$2"/"$3]=++order;
  FS=";";
  ARGC=2;
}
mfggames[$3"/"$1] { print(mfggames[$3"/"$1] FS $0); }
' file2 file1 | sort -n | cut -d ';' -f 2-

输出:

Thrust;Thrust;BBC Micro;;;;;;;;;;;;;;
Alien Breed Special Edition '92;Alien Breed Special Edition '92;Amiga;;1992;Team 17;Action / Shooter;;;;;;;;;;
amidar;amidar;Arcade-Vertical;;;;;;;;;;;;;;
mspacman;mspacman;Arcade-Vertical;;;;;;;;;;;;;;

【讨论】:

  • 谢谢,库巴托。但我需要顺序与我的顺序相同 - 即与 File1/File3 相同的顺序 - 不像你的输出那样排序。
  • 基本上,File1 需要指定文件顺序。
  • 好的,在我的回答中添加为“按 file1 解决方案排序”。不幸的是,这在原始问题中没有得到强调。
  • 谢谢。这似乎对我有用。请问是否可以将这段代码放在一行上?如果没有,那很好。我会赞成你的解决方案。再次感谢您。
  • 一行?是的,只需删除 NL: awk 'BEGIN { if ( ARGC != 3 ) exit(1); FS="/";而 ( getline
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
相关资源
最近更新 更多