需要将文件的最后一行移到同一文件的第二行


8

我在linux中有以下数据的文件“ test”。

aaaaaa
bbbbbb
cccccc
dddddd
eeeeee

我需要剪切此文件的最后一行并将其放在第二个位置。它必须如下所示。

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

Answers:


9

实际上,使用此问题可能最容易解决ed,因为它基本上是可编写脚本的文本编辑器,而不是流处理器。使用ed,您不必将文件的所有行都保存到数组中,例如,因为它已经为您完成了。

# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee

# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

5

保持缓冲区方法:

sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN

...会H老化所有!不是第一行的行,而第一行会p漂洗。在$最后一行用电子邮件x的变化保持和模式空间之前,它的H老-这将追加到最后一行的保存线-然后d从输出eletes这些都是行!不是$最后一次。

$最后一行,它x再次更改空格,s///取消第一个\newline字符(它照顾了第2行中添加的额外字符),然后自动打印批次。

输出:

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

不使用Hold缓冲区:

cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN

...只是将您的示例保存到实际文件中...

sed '1p;$!d;r infile' <infile | sed '3d;$d'

那会重定向<infile到first sedstdin,它只会p冲洗掉第一行,然后d才从输出中删除!不是$最后一行的所有行。最后一行是autoprinted,但它也是在其上执行的最后命令的唯一行-这是rEAD出整个infile 再次stdout。所有这些都通过|管道传递到第二个管道sed,然后只需d从其输出中删除其第三条和最后一条输入线即可完成重新排列。

输出:

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

酷,+ 1。我不记得您曾经发布过awk解决方案,您是sed忠实粉丝还是写信sed?;-)
iruvar 2014年

@ 1_CR-我不知道如何使用awk-我从未尝试过。也许有一天...
mikeserv 2014年

2

使用awk的幼稚方法:

~$ awk '{a[NR]=$0}END{print a[1];print a[NR];for(i=2;i<NR;i++){print a[i]}}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

您将每一行存储在a数组中,然后按所需顺序打印数组(第一行,最后一行(NR),从2开始倒数第二行。

结合使用头/尾和sed:

~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

打印第一行,最后一行,并用sed删除第一行和最后一行。


仅使用sed,我只能找到此命令。我相信有更好的方法:

~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

如果是第一行,则将其打印(默认)。
从第二行开始,将其放入保持缓冲区(H),然后从模式空间(d)中删除。如果是最后一行,请打印(p),然后获取保留缓冲区(x),删除空行(s/^\n//)并打印(p)。


我的第一个直觉是使用头/尾法。该sed部分的替代方案可能是head -n -1 f | tail -n +2
Sparhawk

@Sparhawk的-1语法head不可移植。
mikeserv 2014年

1

使用perl:

perl -e 'my @lines = <>; print for @lines[0, $#lines, 1..$#lines-1]' file

用awk:

$ awk '
    {lines[NR]=$0}
    END{
        print lines[1], lines[NR];
        for (i=2; i<NR; i++) {print lines[i]}
    }
' OFS=$'\n' file

输出值

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
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.