如何从包含另一个文件中列表中的字符串的文本文件中提取行?

abn*_*nry 5 string search

我有一个包含一堆城镇人口信息的文件。我有另一个文件,它是这些城镇子集名称的列表。我想使用第二个文件从第一个文件中选择人口信息。我该怎么做?

例子:

文件 1: ma-towns.txt

Acton   Town    Middlesex   Open town meeting   21,924  1735  
Acushnet    Town    Bristol Open town meeting   10,303  1860  
Adams   Town    Berkshire   Representative town meeting 8,485   1778  
Agawam  City[4] Hampden Mayor-council   28,438  1855  
Alford  Town    Berkshire   Open town meeting   494 1773  
Amesbury    City    Essex   Mayor-council   16,283  1668  
Amherst Town    Hampshire   Representative town meeting 37,819  1775  
Run Code Online (Sandbox Code Playgroud)

文件2: town-list.txt

Acton  
Adams  
Agawam 
Run Code Online (Sandbox Code Playgroud)

期望的输出是

Acton   Town    Middlesex   Open town meeting   21,924  1735  
Adams   Town    Berkshire   Representative town meeting 8,485   1778  
Agawam  City[4] Hampden Mayor-council   28,438  1855   
Run Code Online (Sandbox Code Playgroud)

基本上,如一般所说,如果该行包含文件 2 的其中一行中的字符串,则提取该行。

Sco*_*der 7

grep -f <(sed 's/.*/\^&\\>/' town-list.txt) ma-towns.txt
Run Code Online (Sandbox Code Playgroud)

解释:

grep -f file读取file要匹配的模式列表。我们正在ma-towns.txt列表中搜索,使用来自 的模式town-list.txt。每个单独的行都被视为一个新模式,即一个新的搜索词。

但是,这还不够,所以我添加了 ased来格式化搜索词,如下所示:

^Acton\>
^Adams\>
^Agawam\>
Run Code Online (Sandbox Code Playgroud)

^品牌的grep仅在一行的开始匹配这个模式,和\>品牌的grep只在这一点上,如果匹配的话结束。

这一起确保搜索词只查看行的开头(城镇名称所在的位置),并且搜索词必须在城镇名称结束的地方结束。


sed 命令本身运行一个s(替代)命令,形式为s/search/replace/.

搜索词.*匹配整行。替换 ,\^&\\>将其替换为文字^字符,后跟原始行,后跟文本\>


这个答案做了什么,另一个没有:

  • 处理以破折号开头或包含反斜杠的城镇名称(这不太可能,但如果输入来自用户,您不希望他们能够以不可预测的方式破坏您的脚本)。请注意,这两个答案都将城镇名称视为正则表达式而不是字面搜索词。
  • 按照 ma-towns.txt 中指定的原始顺序输出城镇
  • 表现更好
  • 在行的开头搜索城镇名称,而不仅仅是行中的任何地方
  • 如果只有子字符串匹配,则不匹配城镇(例如Waterloo不会匹配Waterlooville


maz*_*azs 5

这将读取的线条file2和解析file1grep使用的线路:

while read line; do
  grep "${line}" file1
done < file2
Run Code Online (Sandbox Code Playgroud)

  • 如果 `file2` 有 10000 行,你将运行 `grep` 10000 次,读取 `file1` 10000 次 - 所有这些都是通过缓慢且容易出错的 `while..read`... (4认同)