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

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

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

例子:

文件一: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  

文件2:town-list.txt

Acton  
Adams  
Agawam 

期望的输出是

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   

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

答案1

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

解释:

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

然而,这还不够,所以我添加了一个sed来格式化搜索词,如下所示:

^Acton\>
^Adams\>
^Agawam\>

使^grep 仅匹配行开头的模式,并且\>使 grep 仅匹配该单词在该点的结尾。

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


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

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


这个答案做了哪些其他答案没有做的事情:

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

答案2

这将读取以下行file2file1使用grep以下行进行解析:

while read line; do
  grep "${line}" file1
done < file2

相关内容