XからYまでの数字を含む行をZ行の後に別のファイルに挿入する方法は?

XからYまでの数字を含む行をZ行の後に別のファイルに挿入する方法は?

私は2つのファイルを作成しました。

echo -e "1\n2\n3\n4\n5" > 123.txt
echo -e "a\nb\nc\nd\ne" > abc.txt

123.txt以下を含むファイルを取得したいと思います。

1
2
3
b
c
d
4
5

つまり、abc.txtファイルの3行目の後にファイルの2〜4行を挿入します123.txt

ここで同様の質問をたくさん見ましたが、適切な答えが見つかりませんでした。それでも、次のような行があります。

sed -n '2,4p' abc.txt

ファイルの3行目の後にテキストを入力してください。

sed -i '3a\mytext' 123.txt

以前のコマンドstdoutまたは/and sed/単一のコマンドを使用してawkこれをどのように実行できますか?

答え1

システムにGNUバージョンがある場合は、sedGNU拡張コマンドを使用できますr

r filename
    As a GNU extension, this command accepts two addresses.

    Queue the contents of filename to be read and inserted into the
    output stream at the end of the current cycle, or when the next input 
    line is read. Note that if filename cannot be read, it is treated as 
    if it were an empty file, without any error indication.

    As a GNU sed extension, the special value /dev/stdin is supported for 
    the file name, which reads the contents of the standard input. 

例えば、

$ sed '3r /dev/stdin' 123.txt < <(sed -n '2,4p' abc.txt)
1
2
3
b
c
d
4
5

答え2

awkとを使用してsed

$ awk 'FNR==3{print;system("sed -n '2,4p' abc.txt");next};1' 123.txt 
1
2
3
b
c
d
4
5

答え3

Passを使用するsedと、このrコマンドを使用してファイル全体を挿入できます。ファイルの一部を挿入するには、その部分を抽出して入力にパイプすることもできますsedsed

sed -n '2,4p' abc.txt | sed -i '3r /dev/stdin' 123.txt

を使用すると、awkあるファイルを読み取り、途中で別のファイルに切り替えることができます。

awk <123.txt >123.txt.new '
    1                                    # print the input line
    NR==3 {                              # after line 3 of 123.txt, …
        while (getline < "abc.txt") {
            ++inner_NR;
            if (inner_NR >= 2) print;    # start printing at line 2 from abc.txt
            if (inner_NR == 4) break;    # stop after line 4
        }
    }
' &&
mv 123.txt.new 123.txt

マージしたいファイルの部分を抽出するためにおよびheadを使用することもできます。tail

head -n 3 <123.txt >123.txt.new &&
<abc.txt tail -n +2 | head -n 3 >>123.txt.new &&
tail -n +4 123.txt >>123.txt.new &&
mv 123.txt.new 123.txt

head+tailメソッドとを組み合わせることができますsed。大容量ファイルの場合、この方法はおそらく最速です。

<abc.txt tail -n +2 | head -n 3 | sed -i '3r /dev/stdin' 123.txt

これらのメソッドはすべて移動された一時ファイルに書き込まれます123.txt(使用されているメソッドも同じです。これは後ろに起こるためsed -iです)。sed -i

答え4

ed内部編集に使用しますsed(bashプロンプトで):

ed -s 123.txt<<<$'3r !sed -n "2,4p" abc.txt\nw'

関連情報