複数のテキストファイルで行を移動する方法は? [コピー]

複数のテキストファイルで行を移動する方法は? [コピー]

こんにちは、次のようなファイルがあるとしましょう。

x
x
x
A
B
C
1
2
3
D
E
F
x
x
x

ファイルは次のようにする必要があります。

x
x
x
A
B
C
D
E
F
1
2
3
x
x
x

いくつかの行でこれを行うことができることを知っていますが、数字をどの方向にも行を移動するsed -i s/search/replace/gより良いより簡単な方法があるかどうか疑問に思います。xy

答え1

編集する

echo -e '7,9m12\n,p' | ed -s file.txt

答え2

以下を使用してくださいsed(ストリームエディタで最も簡単な方法なので、行を下に移動します)。

$ sed '7,9{H;d;}; 12{G;s/\n//;}' <file
x
x
x
A
B
C
D
E
F
1
2
3
x
x
x

sedこのスクリプトを「12行目の後に7〜9行移動」と解釈できます。

スクリプトのコメントは次のとおりです。

7,9{            # These are the lines we'd like to move
    H;          # Append them to the hold space (separated by newlines)
    d;          # Delete from pattern space, start next cycle
}
12{             # This is where we'd like to move those lines
    G;          # Append the hold space
    s/\n//;     # Remove the newline that the above command inserted
}
                # (implicit print)

行は行番号だけでなく正規表現として扱うことができるため、以下も機能します(この特定のデータの場合)。

sed '/^1/,/^3/{H;d;}; /^F/{G;s/\n//;}' <file

つまり、「で始まる行から始まる行に移動し、」で始まる行の後に1移動します。3F


上記を次のように直接翻訳してくださいawk

awk '/^1/,/^3/ { hold = hold ORS $0; next }
     /^F/      { $0 = $0 hold }
               { print }' <file

「行番号」(レコード番号awk)を使用する:

awk 'NR == 7, NR == 9 { hold = hold ORS $0; next }
     NR == 12         { $0 = $0 hold }
                      { print }' <file

条件はNR == 7, NR == 9次のように書くこともできますNR >= 7 && NR <= 9

コードに100%一致するには、sed2番目のチャンクを読む必要がありますが、{ $0 = $0 ORS hold; sub(ORS, "", $0) }出力レコード区切り文字(デフォルトでは改行)を挿入してすぐに削除するのは少し愚かです。


元のファイルを上記のコマンドの結果に置き換えるには、次の手順を実行します。

sed ...as above... <file >newfile && mv newfile file

または command と同じですawk

sed/の入力ファイルをawk読み取れない場合、または出力ファイルを書き込めない場合、元のファイルは変更されません。

関連情報