Bash:按行号过滤行

rmf*_*rmf 7 sed awk text-processing

如果我有一个包含多行和多列 ( data.txt)的分隔文件:

346 dfd asw  34
565 sd  wdew 34
667 ffg wew  23
473 sa  as   21
533 jhf qwe  54
Run Code Online (Sandbox Code Playgroud)

和另一个我想提取行号的文件 ( positions.txt)

3
5
8
Run Code Online (Sandbox Code Playgroud)

如何使用该positions.txt文件从中提取这些位置data.txt?这是我对这个例子期望的结果:

667 ffg wew  23
533 jhf qwe  54
Run Code Online (Sandbox Code Playgroud)

Rom*_*est 8

只需awk

awk 'NR==FNR{ pos[$1]; next }FNR in pos' positions.txt data.txt
Run Code Online (Sandbox Code Playgroud)
  • NR==FNR{ ... }- 处理第一个输入文件(即positions.txt):
    • pos[$1]- 累积位置(记录数)设置为pos数组键
    • next - 跳到下一个记录
  • FNR in pos- 在处理第二个输入文件时data.txtFNR表示从当前输入文件中读取了多少记录)。仅当当前记录号FNR在位置数组中时才打印记录pos(搜索键)

示例输出:

667 ffg wew  23
533 jhf qwe  54
...
Run Code Online (Sandbox Code Playgroud)


Kus*_*nda 5

首先sedpositions.txt文件创建一个脚本:

sed 's/$/p/' positions.txt
Run Code Online (Sandbox Code Playgroud)

这将输出

3p
5p
8p
Run Code Online (Sandbox Code Playgroud)

这个简单的脚本将只打印指定的行。

然后将其应用于data.txt文件。如果您正在使用bash(或任何理解进程替换的 shell <( ... )):

sed -n -f <( sed 's/$/p/' positions.txt ) data.txt
Run Code Online (Sandbox Code Playgroud)

除了给定脚本明确打印的内容之外,-n停止sed输出任何内容sed

通过给出的例子,这将产生

667 ffg wew  23
533 jhf qwe  54
Run Code Online (Sandbox Code Playgroud)

如果不使用bash,那么

sed 's/$/p/' positions.txt >filter.sed
sed -n -f filter.sed data.txt
rm -f filter.sed
Run Code Online (Sandbox Code Playgroud)

......会做同样的事情。