我有一个包含一些城镇人口信息的文件。我有另一个文件,它是这些城镇子集的名称列表。我想使用第二个文件从第一个文件中选择人口信息。我该怎么做?
例子:
文件一: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
这将读取以下行file2
并file1
使用grep
以下行进行解析:
while read line; do
grep "${line}" file1
done < file2