使用 sed 从文本文件中删除特定行号?

问题描述 投票:0回答:8

我想从文件中删除一个或多个特定的行号。我将如何使用 sed 执行此操作?

unix sed line-numbers
8个回答
514
投票

如果要删除第 5 到 10 行和第 12 行:

sed -e '5,10d;12d' file

这会将结果打印到屏幕上。如果要将结果保存到同一个文件:

sed -i.bak -e '5,10d;12d' file

这会将未修改的文件存储为

file.bak
,并删除给定的行。

注意:行号从1开始。文件的第一行是1,不是0。


115
投票

您可以删除带有行号的特定单行

sed -i '33d' file

这将删除第 33 行号上的行并保存更新的文件。


27
投票

还有 awk

awk 'NR!~/^(5|10|25)$/' file

23
投票
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$ 

8
投票

这通常是反模式的症状。生成行号的工具很可能会被立即删除行的工具所取代。例如;

grep -nh error logfile | cut -d: -f1 | deletelines logfile

(其中

deletelines
是您想象中需要的实用程序)与

相同
grep -v error logfile

话虽如此,如果您确实需要执行此任务,则可以从行号文件生成一个简单的

sed
脚本。幽默地(但可能有点令人困惑)你可以用
sed
来做到这一点。

sed 's%$%d%' linenumbers

这接受一个行号文件,每行一个,并在标准输出上生成相同的行号,并在每个行号后附加

d
。这是一个有效的
sed
脚本,我们可以将其保存到文件中,或者(在某些平台上)通过管道传输到另一个
sed
实例:

sed 's%$%d%' linenumbers | sed -f - logfile

在某些平台上,

sed -f
不理解选项参数
-
的意思是标准输入,因此您必须将脚本重定向到一个临时文件,并在完成后清理它,或者将单独的破折号替换为
/dev/stdin
/proc/$pid/fd/1
如果你的操作系统(或外壳)有。

与往常一样,您可以在

-i
选项之前添加
-f
以让
sed
就地编辑目标文件,而不是在标准输出上生成结果。在 *BSDish 平台(包括 OSX)上,您还需要为
-i
提供一个显式参数;一个常见的习惯用法是提供一个空的参数;
-i ''
.


4
投票

最短,删除
sed

中的第一行

sed -i '1d' file

正如布赖恩所说这里,使用

<address><command>
<address>
<1>
<command>
<d>
.


3
投票

我想用 awk 提出一个泛化。

当文件由固定大小的块组成时 并为每个块重复要删除的行, awk 可以以这种方式正常工作

awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print  $0}'
 OriginFile.dat > MyOutputCuttedFile.dat

在此示例中,块的大小为 2000,我想打印行 [1..713] 和 [1026..1029]。

  • NR
    是awk用来存储当前行号的变量。
  • %
    给出两个整数相除的余数(或模数);
  • nl=((NR-1)%BLOCKSIZE)+1
    这里我们在变量 nl 中写入当前块内的行号。 (见下文)
  • ||
    &&
    是逻辑运算符ORAND.
  • print $0
    写下整行

Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
  +1   We add again 1 because we want to restore the desired order.

+-----+------+----------+------------+
| NR  | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
|  1  |  1   |    0     |     1      |
|  2  |  2   |    1     |     2      |
|  3  |  0   |    2     |     3      |
|  4  |  1   |    0     |     1      |
+-----+------+----------+------------+


0
投票

cat -b /etc/passwd | sed -E 's/^( )+(<line_number>)(\t)(.*)/--removed---/g;s/^( )+([0-9]+)(\t)//g'

cat -b
-> 用数字打印行

s/^( )+(<line_number>)(\t)(.*)//g
-> 将行号替换为空(删除行)

s/^( )+([0-9]+)(\t)//g
#删除
cat
打印的数字

© www.soinside.com 2019 - 2024. All rights reserved.