在给定的行号上执行sed操作


8

我想知道是否有一种简单的方法可以在具有预分配行号的某些行上进行操作。

假设我要输出文件的第1、7、14和16行,我可以简单地执行

sed -n '1p;7p;14p;16p' input_file

但这在操作不仅是打印时变得更加复杂,而且我不想编写相同的长命令4次(是的,我知道我可以通过替换相同的bash变量4次来构造此long sed命令,但是这还不够理想...),即

sed -n '1{long_command};7{long_command};14{long_command};16{long_command}' input_file

有没有办法对文件的这些特定行进行操作?我期待这样的事情,

sed -n '1,7,14,16p'

这肯定无法在当前形式下运行。

任何帮助将不胜感激。“不,这不可能。” 解释也是我会接受的答案。


很容易awk
RomanPerekhrest18年

Answers:


11

您可以使用分支:

sed '
  1b1
  7b1
  14b1
  16b1

  # for the rest to be left alone, branch off (or delete them with "d"):
  b

  :1
  long_command'

(请注意,您还可以添加一些20,25b1行范围,或/re/b1包含与匹配的行re)。

或者您可以使用awk

awk 'NR == 1 || NR == 7 || ... {stuff}'

或使用哈希:

awk -v l=1,7,14,16 '
  BEGIN{split(l, a, ","); for (i in a) lines[a[i]]}

  NR in lines {stuff}'

(或者BEGIN{lines[1]lines[7]lines[14]lines[16]}如果没有太多)


谢谢,从未想过分支机构……这似乎是在这种情况下使用的理想工具。

如何在搜索模式中使用像这样的分支?像说我要匹配或删除第n行之后的模式?
qodeninja

3

只需反转您的选择并将其删除:

sed '2,6d;8,13d;15d;17,$d;long_command'

这也是一个不错的解决方案,尽管例如处理从stdin读取的行号要困难一些。

1

第一个变体:

您可以使用以下技巧:

sed -nf <(printf '%dp\n' 1 7 14 16)

-f 脚本文件 -将脚本文件的内容添加到要执行的命令中。

测试中

seq 1 20 | sed -nf <(printf '%dp\n' 1 7 14 16)

输出量

1
7
14
16

第二个变体:

最初,辅助程序sed仅用于过滤文件中所需的行,然后sed使用long命令将这些行通过管道传输到主行。

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.