bash 別のファイルに基づくファイルに複数の空行を挿入する方法

bash 別のファイルに基づくファイルに複数の空行を挿入する方法

bashを使用して、インデックスファイル(file2と呼ばれる)に基づいてファイル(file1と呼ばれる)に複数の空行を挿入するのに少し難しいことがあります。 (これらのファイルは渡された変数と見なすことができます。)インデックスファイル(file2)は次のとおりです。

-
-
-
M
H
A
-
N
X
X
M
-
-
-
F
G
A
...

file1 は次のようになります。

M   x1 y1 z1 m1 n1
H   x2 y2 z2 m2 n2
A   x3 y3 z3 m3 n3
N   x4 y4 z4 m4 n4
X   x5 y5 z5 m5 n5
X   x6 y6 z6 m6 n6
M   x7 y7 z7 m7 n7
F   x8 y8 z8 m8 n8
G   x9 y9 z9 m9 n9
A   x0 y0 z0 m0 n0
...

出力は次のようになります。

-
-
-
M   x1 y1 z1 m1 n1
H   x2 y2 z2 m2 n2
A   x3 y3 z3 m3 n3
-
N   x4 y4 z4 m4 n4
X   x5 y5 z5 m5 n5
X   x6 y6 z6 m6 n6
M   x7 y7 z7 m7 n7
-
-
-
F   x8 y8 z8 m8 n8
G   x9 y9 z9 m9 n9
A   x0 y0 z0 m0 n0
...

file2 が '-' を削除すると、内容と順序は常に file1 の最初の列と同じです。

Pythonのデータフレームとして扱ってみましたが、遅すぎます。だからbashを使ってこの問題を解決する方法を知りたいです。ありがとうございます!

答え1

インデックスファイル内の文字が常に正しい順序の正しい文字であり(表示されている文字を無視できるように)、空の行に実際にダッシュが含まれていて完全に空ではないと仮定すると、次のようになります。

$ awk -v datafile=data.txt '$1 == "-" { print "-"; next} { getline < datafile; print }' < index.txt 
-
-
-
M   x1 y1 z1 m1 n1
H   x2 y2 z2 m2 n2
A   x3 y3 z3 m3 n3
-
N   x4 y4 z4 m4 n4
X   x5 y5 z5 m5 n5
X   x6 y6 z6 m6 n6
M   x7 y7 z7 m7 n7
-
-
-
F   x8 y8 z8 m8 n8
G   x9 y9 z9 m9 n9
A   x0 y0 z0 m0 n0
...

インデックスファイルを一度に1行ずつ読み込みます。最初のフィールドがある場合は-それを印刷し、そうでない場合は別のファイルから1行を読み取り、印刷します。 (つまり、インデックスファイルに完全に空の行が表示された場合は、データファイルの次の行に移動することを意味します。)

答え2

GNU sedを使用して、2つのファイルの最初の文字の順序がまったく同じであると仮定し、次の行を無視し、-各「文字」行ごとに1行を読み込み、挿入します。file1file2

$ sed -e '/^[A-Z]/{R file1' -e 'd;}' file2
-
-
-
M   x1 y1 z1 m1 n1
H   x2 y2 z2 m2 n2
A   x3 y3 z3 m3 n3
-
N   x4 y4 z4 m4 n4
X   x5 y5 z5 m5 n5
X   x6 y6 z6 m6 n6
M   x7 y7 z7 m7 n7
-
-
-
F   x8 y8 z8 m8 n8
G   x9 y9 z9 m9 n9
A   x0 y0 z0 m0 n0

答え3

file2をインデックスファイル、file1をデータファイルとしてPOSIX sed、インデックスファイルを使用して最初にsedコードを生成し、それをデータファイルに適用して目的の最終出力を取得します。

sed '
  1{
    x;s:.*:H;s/.*/-/;x:;x
    i\
x;s/.*/-/;x
    :loop
      /^-/!d;g;n
    b loop
  }
  /^-/s/.*/G/;t
  c\
n
' file2 |sed -f - file1

出力:-

-
-
-
M   x1 y1 z1 m1 n1
H   x2 y2 z2 m2 n2
A   x3 y3 z3 m3 n3
-
N   x4 y4 z4 m4 n4
X   x5 y5 z5 m5 n5
X   x6 y6 z6 m6 n6
M   x7 y7 z7 m7 n7
-
-
-
F   x8 y8 z8 m8 n8
G   x9 y9 z9 m9 n9
A   x0 y0 z0 m0 n0

答え4

for j in $(awk '/-/{print NR}' file2); do sed -i ''$j'i -' file1; done

出力

cat file1
-
-
-
M   x1 y1 z1 m1 n1
H   x2 y2 z2 m2 n2
A   x3 y3 z3 m3 n3
-
N   x4 y4 z4 m4 n4
X   x5 y5 z5 m5 n5
X   x6 y6 z6 m6 n6
M   x7 y7 z7 m7 n7
-
-
-
F   x8 y8 z8 m8 n8
G   x9 y9 z9 m9 n9
A   x0 y0 z0 m0 n0

関連情報