![如何提取文本文件中的特定行以及包含特定字符串的多行?](https://linux22.com/image/124518/%E5%A6%82%E4%BD%95%E6%8F%90%E5%8F%96%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E7%89%B9%E5%AE%9A%E8%A1%8C%E4%BB%A5%E5%8F%8A%E5%8C%85%E5%90%AB%E7%89%B9%E5%AE%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%A4%9A%E8%A1%8C%EF%BC%9F.png)
我有一个文本文件集合,其中包含的数据多于我需要的数据。每个文件的第一行包含一个逗号分隔字符串看起来像这样:
stop_id,stop_code,stop_name,stop_desc,stop_lat,stop_lon,location_type,parent_station,zone_id
然后,这些键下面是所有数据。我需要将该数据的子集提取到一个新的文本文件中,以便我可以使用该子集(我不需要所有数据,它太多了)。
我正在使用此命令来提取第一行:
sed -n '1p' source.txt > destination.txt
我还使用此命令来提取我需要的特定行:
grep "string" source.txt > destination.txt
挑战在于,当我在同一脚本中运行这两个命令时(几乎按原样,用行 或 分隔&&
),grep
输出会覆盖sed
输出。如何按顺序运行两者并获得两者的组合输出?
我注意到一个看起来相似的问题,涉及使用更复杂的grep
命令来定位一行,然后是一系列行。这在这里不起作用,因为我需要从中提取数据的每个文件的第一行都是不同的。
理想情况下,我想编写一个可以针对我需要使用的每个文件运行的函数,但我需要先链接这些命令并组合它们的输出。
答案1
sed
可以完成这两项工作(打印第一行和包含 的所有行string
):
sed -n '1p; /string/p' source.txt > destination.txt
或更长的版本:
sed -n -e '1p' -e '/string/p' source.txt > destination.txt
答案2
只需将grep
输出更改为附加,
grep "string" source.txt >> destination.txt
答案3
有很多方法可以做到这一点。您可以使用单个命令来获取这两行,如下所示@Cyrus 的sed
解决方案确实如此。以下是一些可以执行此操作的其他工具:
awk 'NR==1 || /string/' source.txt > destination.txt
perl -ne 'print if /string/ || $. ==1' source.txt > destination.txt
当然,您也可以运行您正在运行的两个命令,只需更改第二个命令即可附加到文件中正如班乔萨建议的那样。或者,您可以将两个命令分组在一个子 shell 中,并将子 shell 的输出重定向到一个文件:
(sed -n '1p' file; grep string file) source.txt > destination.txt
或者
{ sed -n '1p' file; grep string file; } source.txt > destination.txt
因此,如果您想要做的是用这些函数创建一个函数,那么就像将其添加到 shell 的初始化文件中一样简单(例如~/.bashrc
):
foo(){ sed -n '1p' file; grep string file; }
现在您可以运行该函数foo
来执行您想要的操作:
foo source.txt > destination.txt