ファイルの特定の行を他のファイルの値に置き換える

ファイルの特定の行を他のファイルの値に置き換える

file12、6、7行を各行の値に置き換えて、次のようなfile2系列を作成したいと思います。wc -l file2

cat file1
w
3
y
G
7
1.2
Q
cat file2
1        1        1
6        6        7
5        6        5

予想される結果:

cat out1
w
1
y
G
7
1
1
cat out2
w
6
y
G
7
6
7
cat out3
w
5
y
G
7
6
5

答え1

awk '
    FNR == NR { data[++n] = $0; next }
    {
        data[2] = $1; data[6] = $2; data[7] = $3;
        outname = sprintf("out%d", FNR)  # or: outname = "out" FNR
        for (i = 1; i <= n; ++i)
            print data[i] >outname
        close(outname)
    }' file1 file2

file1この内容を最初に読み、次に読みますfile2

file1(チャンクとして)読み取り中にFNR == NRコードが行う唯一の作業は、awk各行を配列に保存することですdata

読み取ると、file2コードはファイルの1行にある3つのフィールドをそれぞれ取得し、変更する行に対応するdataインデックスに割り当てますfile1

保存された行は現在の行番号を取り、その前に文字列を追加して設定されたファイル名dataで印刷されます。file2out

close(outname)awkこれは、実際にはGNU以外のものを使用し、記録されたawkファイル数が開かれたファイル記述子制限を超える場合にのみ必要です(返された数を超え、ulimit -n標準ストリームの場合は3つ減算)。

テスト:

$ tree
.
|-- file1
`-- file2

0 directory, 2 files
$ awk '
    FNR == NR { data[++n] = $0; next }
    {
        data[2] = $1; data[6] = $2; data[7] = $3;
        outname = sprintf("out%d", FNR)
        for (i = 1; i <= n; ++i)
            print data[i] >outname
        close(outname)
    }' file1 file2
$ tree
.
|-- file1
|-- file2
|-- out1
|-- out2
`-- out3

0 directory, 5 files
$ paste out[123]
w       w       w
1       6       5
y       y       y
G       G       G
7       7       7
1       6       6
1       7       5

答え2

$ cat tst.awk
BEGIN {
    split("2 6 7",tmp)
    for (fldNr in tmp) {
        map[tmp[fldNr]] = fldNr
    }
}
NR==FNR {
    rows[++numRows] = $i
    next
}
{
    out = "out" FNR
    for (rowNr=1; rowNr<=numRows; rowNr++) {
        print (rowNr in map ? $(map[rowNr]) : rows[rowNr]) > out
    }
    close(out)
}

$ awk -f tst.awk file1 file2

$ head out?
==> out1 <==
w
1
y
G
7
1
1

==> out2 <==
w
6
y
G
7
6
7

==> out3 <==
w
5
y
G
7
6
5

答え3

使用GNU sedout_0/1/2 ファイル内の file2 の各行の出力を取得します。

tmpf=$(mktemp) i=0
while read -ra a <&3
do
   printf '%s\n' "${a[@]}" > "$tmpf"
   sed -ne "
      $(printf '%dba\n' 2 6 7)
      p;d;:a
      R $tmpf
   " file1 > "out_$i"
    (( i++ ))
done 3< file2
  • whileループからfile2を読み取り、スペースで区切られたフィールドを改行区切りフィールドに変換して一時ファイルに保存します。
  • get sed は、目的の出力を得るために file1 の行 2,6,&7 で R コマンドを呼び出します。

関連情報