从文本文件中删除除第n个和第n个以外的行

时间:2018-09-11 22:01:45

标签: bash awk sed

我有一个由数字组成的长文本文件,例如:

1
2
9.252
9.252
9.272
1
1
6.11
6.11
6.129

我想保留第一行,删除后面的三行,然后保留下一行。我想对整个文件执行此过程。按照上述输入的逻辑,我希望获得以下输出:

1
9.272
1
6.129

6 个答案:

答案 0 :(得分:5)

使用GNU sed~扩展名需要):

sed -n '1~5p;5~5p' file

答案 1 :(得分:4)

将您的号码保存在“ textfile.txt”中,我可以在sed中使用以下内容:

sed -n 'p;n;n;n;n;p;' textfile.txt

Sed打印第一行,读取下4行并打印最后一行。

或者在bash中使用while read进行以下操作:

while read -r firstline && read -r nextone1 && read -r nextone2 && read -r nextone3 && read -r lastone; do 
    printf "%s\n" "$firstline" "$lastone"; 
done < textfile.txt

这一次只能读取5行,并且仅打印第一行和第五行。

答案 2 :(得分:3)

您可以简单地说:

awk 'NR%5<2' input.txt

说明::考虑到整个模式每五行重复一次,让我们开始对行号NR乘以5进行模运算。然后,我们将看到五行代码块的第一行产生“ 1”,而五行代码块的第五行产生“ 0”。现在,可以通过将它们进行比较以将它们与其他行分开。

答案 3 :(得分:2)

要打印每行5行的第1行和第5行(请记住5%5 = 0):

$ awk '(NR%5) ~ /[10]/' file
1
9.272
1
6.129

如果要打印每行5行的第二行,第三行和第四行,而不是第一行和第五行:

$ awk '(NR%5) ~ /[234]/' file
2
9.252
9.252
1
6.11
6.11

如果要打印每100个块的第27行和第53行:

awk '(NR%100) ~ /^(27|53)$/' file

我们无法在此处使用方括号表达式,因为我们现在已经超出了单个字符数。

答案 4 :(得分:1)

这可能对您有用(GNU sed):

sed '2~5,+2d' file

从第2行开始,使用模5删除接下来的三行。

替代方法:

sed -n '1p;5~5,+1p' file

答案 5 :(得分:0)

考虑到您的组被打包成5行,您可以将awkmod 5操作结合使用。

awk '{i=(NR-1)%5;if(i==0||i==4)print $0}' input.txt

缩进后看起来像这样:

{
  i=(NR-1)%5;
  if (i==0||i==4)
    print $0;
}

i=(NR-1)%5获取行号并以5计算模数,但是由于行号从1开始(而不是0),因此在计算模数之前您需要减去1。

这将为您提供范围为0到4的整数i。您要打印第一行(索引0),跳过后三行(索引1-3),然后打印最后一行(索引4),这正是if (i==0||i==4) print $0

的作用

或者,您可以使用更短的版本(可能稍微更优化的版本)执行相同的操作:

awk '((NR-1)%5==0||(NR-1)%5==4)' input.txt

这告诉awk对5行中的第1行和5行中的第5行执行某项操作。由于未定义“内容”,因此默认情况下它将输出当前行。如果有帮助,则严格等于:

awk '((NR-1)%5==0||(NR-1)%5==4){print $0}' input.txt