我们说我有这个清单:
apple
orange
banana
kiwi
strawberry
如何将第2行(orange
)的值与第4行(kiwi
)的值交换以获得此结果:
apple
kiwi # before "orange"
banana
orange # before "kiwi"
strawberry
答案 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行组合了e
和d
命令,每个命令都提取所需的行并删除当前行。也许有可能不诉诸-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。这可以用来替换任何一对线(甚至相邻的线)。