sed特定行号替换(交换)

时间:2016-03-27 22:13:53

标签: bash sed

我们说我有这个清单:

apple
orange
banana
kiwi
strawberry

如何将第2行(orange)的值与第4行(kiwi)的值交换以获得此结果:

apple
kiwi # before "orange"
banana
orange # before "kiwi"
strawberry

4 个答案:

答案 0 :(得分:1)

对于专门处理第2和第4行的解决方案:

$ sed '2{N;N;s/^\(.*\)\(\n.*\n\)\(.*\)$/\3\2\1/}' infile
apple
kiwi
banana
orange
strawberry

当到达第2行时,这会将下两行添加到模式空间,然后交换第一行和最后一行。

要使用相同的方法来概括这一点,N(和第二个捕获组中的\n)的数量必须相应增加,最好的选择可能是写一个脚本到生成sed命令。

另一个选项,但GNU特定于sed:e命令,它允许将shell命令的结果传递给模式空间。

sed -e '2{e'"sed -n '4{p;q}' infile" -e 'd}' \
-e '4{e'"sed -n '2{p;q}' infile" -e 'd}' infile
1 apple
4 kiwi
3 banana
2 orange
5 strawberry

这为第2行和第4行组合了ed命令,每个命令都提取所需的行并删除当前行。也许有可能不诉诸-e分裂命令,但逃避得非常混乱。

答案 1 :(得分:0)

不知道如何使用sed,但使用gnu awk,你可以这样做(使用fruits.txt中的列表):

awk -v 'FS=\n' -v 'OFS=\n' -v 'RS=' '1 {print $1, $4, $3, $2, $5}' fruits.txt

各种-v ...设置输入和输出字段分隔符到换行符,并清除记录分隔符。

答案 2 :(得分:0)

awk救援!

$ awk -v first=2 -v second=4 'FNR==NR{if(NR==second)s=$0; next}
                           FNR==first{f=$0; $0=s}
                           FNR==second{$0=f} 1' fruits{,} 

apple
kiwi
banana
orange
strawberry

通过双重扫描文件来交换第一个和第二个变量指定的行。

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed -r '2{:a;N;4!ba;s/([^\n]*)(\n?.*\n)(.*)/\3\2\1/}' file

聚焦在第2行并将线条附加到图案空间(PS),直到所需的线条(在本例中为第4行)。然后使用模式匹配对线进行重新排序。

N.B。这可以用来替换任何一对线(甚至相邻的线)。