ファイルの最後の行を同じファイルの2行目に移動する必要がある


8

以下のデータを含むファイルがLinuxにあります。

aaaaaa
bbbbbb
cccccc
dddddd
eeeeee

このファイルの最後の行を切り取り、2番目の位置に配置する必要があります。以下のようになります。

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

回答:


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///最初ubstitutes離れて\n2行目に追加の余分の世話をする- -そして、多くのことをautoprints ewline文字が。

出力:

aaaaaa
eeeeee
bbbbbb
cccccc
dddddd

保留バッファを使用しない場合:

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

...例を実際のファイルに保存するだけです...

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

これ<infileは最初のにリダイレクトします。最初sedの行stdinだけをpリントしてdから!$最後の行ではないすべての行を出力から削除します。最後の行はr自動印刷されますが、最後のコマンドが実行される唯一の行でもあります。これにより、全体がinfile 再びに出力さstdoutます。これらすべては|パイプを介して2番目に渡され、3番目と最後の入力行を出力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配列のすべての行を保存してから、配列を必要な順序(1行目、最後の行(NR)、2から2番目まで)で出力します。

ヘッド/テールとセッドの組み合わせを使用:

~$ 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

最初の行の場合は、印刷します(デフォルト)。
2行目から、それをホールドバッファーに入れ(H)、パターンスペースから削除します(d)。そして、それが最後の行である場合は、それを印刷し(p)、次に保留バッファーを取得し(x)、空の行を削除し(s/^\n//)、それを印刷します(p)。


私の最初の本能は、頭/尾の方法を使用することでした。sedパーツの代わりはのようなものhead -n -1 f | tail -n +2です。
スパーホーク2014

@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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.