如何删除文件中的某些行(使用行号)?

tsh*_*ang 27 text-processing

我想从文件中删除一些特定的行。假设它是第 20-37 行,然后是第 45 行。如果不指定这些行的内容,我该怎么做?

pdo*_*pdo 29

随着sed,像这样:

sed '20,37d; 45d' < input.txt > output.txt
Run Code Online (Sandbox Code Playgroud)

如果您想就地执行此操作:

sed --in-place '20,37d; 45d' file.txt
Run Code Online (Sandbox Code Playgroud)

  • 我经常想知道在提到 'sed' 时可能会产生误导的术语 **in-place**,所以我在 'man sed' 中查找: *--in-place[=SUFFIX]* `This option指定文件将被就地编辑。GNU `sed' 通过创建一个临时文件并将输出发送到这个文件而不是标准输出来做到这一点。` ...我不知道任何其他的 'sed' 但是使用*流*编辑器不“计算”:) (3认同)
  • 根据我的经验,大多数“就地”方法使用临时文件。 (2认同)

don*_*sti 5

如果文件适合内存,您也可以使用ed.
这些命令与sed上面的命令非常相似,但有一个显着区别:您必须按降序传递要删除的行号/范围列表(从最高的行号/范围到最低的行)。原因是当您使用 删除/插入/拆分/加入行时ed,文本缓冲区会在每个子命令之后更新,因此如果删除某些行,以下行的其余部分将不再位于缓冲区中的相同位置执行下一个子命令。所以你必须向后开始1
就地编辑:

ed -s in_file <<IN
45d
20,37d
w
q
IN
Run Code Online (Sandbox Code Playgroud)

或者

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
Run Code Online (Sandbox Code Playgroud)

或者

printf '%s\n' 45d 20,37d w q | ed -s in_file
Run Code Online (Sandbox Code Playgroud)

如果要打印结果输出而不是写入文件,请将write替换为,print。如果您想保持原始文件完整并写入另一个文件,您可以将新文件名传递给write 子命令:

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
Run Code Online (Sandbox Code Playgroud)

1 除非您愿意计算每个delete之后的新行号,这对于这种特殊情况来说非常简单(删除第 20-37 行后,即 18 行,第 45 行变为第 27 行),因此您可以运行:

ed -s in_file <<IN
20,37d
27d
w
q
IN
Run Code Online (Sandbox Code Playgroud)

但是,如果您必须删除多个行号/范围,向后工作是很容易的。