あるファイルの空白行を別のファイルの行に置き換える

あるファイルの空白行を別のファイルの行に置き換える

私は持っていますファイル1.csv

"word 1"
""
"word 3"
""
"word 5"
"word 6"

そしてファイル2.csv

"replacement text 1"
"replacement text 2"
"replacement text 3"
"replacement text 4"
"replacement text 5"
"replacement text 6"

file1に空の行(または ""のある行)があることを確認し、それをfile2の内容に置き換えるコマンドを探しています。

これ出力.csvしなければならない

"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

答え1

ファイルの行数が同じであると仮定します。paste最初のファイルのフィールドを無題の最初の列として使用し、2番目のファイルのフィールドを無題の2番目の列として使用してCSVレコードストリームを作成します。

$ paste -d , file1.csv file2.csv
"word 1","replacement text 1"
"","replacement text 2"
"word 3","replacement text 3"
"","replacement text 4"
"word 5","replacement text 5"
"word 6","replacement text 6"

それから私達は利用できますミラー最初のフィールドが空の場合、最初のフィールドを2番目のフィールドの値で更新します。

$ paste -d , file1.csv file2.csv| mlr --csv -N put 'is_empty($1) { $1 = $2 }'
word 1,replacement text 1
replacement text 2,replacement text 2
word 3,replacement text 3
replacement text 4,replacement text 4
word 5,replacement text 5
word 6,replacement text 6

is_empty()そのフィールドが入力で参照されているかどうかにかかわらず、すべての空のフィールドに対してテストが適用されます。

その後、最初のフィールドを切り取り(抽出)できます。

$ paste -d , file1.csv file2.csv| mlr --csv -N put 'is_empty($1) { $1 = $2 }' then cut -f 1
word 1
replacement text 2
word 3
replacement text 4
word 5
word 6

Millerは実際に引用する必要があるフィールドだけを引用します。 Millerにすべての出力フィールドを引用させるには、次のようにします--quote-all

$ paste -d , file1.csv file2.csv| mlr --csv -N --quote-all put 'is_empty($1) { $1 = $2 }' then cut -f 1
"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

このようなことを間違いなく似たようなことをするawk使用awk

$ paste -d , file1.csv file2.csv| awk -F , '$1 == "\"\"" { $1 = $2 } { print $1 }'
"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

答え2

別のawkオプション:

awk '{getline other < "file2.csv"}
     $0 == "\"\"" {$0 = other}
     {print}' file1.csv > output.csv

またはpaste+ sed:

paste -d '\n' file1.csv file2.csv| sed 'N;s/^""\n//;s/\n.*//' > output.csv

file2.csv満足する行が十分でない場合は、すべての""行が 1 に再利用され、最後の行に +1 を使用すると空の行が生成されます。それよりも多くの行がある場合は、そこに追加の空行もあります。file1.csvawkfile2.csvpastesedfile2.csvfile1.csv

答え3

$ awk -F, 'NR == FNR    { a[FNR] = $1; next };
           $1 == "\"\"" { $1 = a[FNR] };
           1' file2.csv file1.csv 
"word 1"
"replacement text 2"
"word 3"
"replacement text 4"
"word 5"
"word 6"

file2.csvを読み込み、各行の列1を配列に保存します。

次に、file1.csvを読み取り、列1が二重引用符のペア(たとえば「空」)の場合、最初の列を配列の適切な要素(FNRまたは現在のファイルの現在行番号)に置き換えます。次に、変更するかどうかに関係なく、現在の行を印刷します。

答え4

次のPerlスクリプトは、元の入力(file1.csv)がstdinであり、代替ファイルがコマンドライン引数として渡されると想定しています。

#!/usr/bin/perl
while (<STDIN>) {
  $_ = <> if /^("")?$/;
  print;
}

たとえば、次のいずれかです。

$ cat file1.csv | perl this-script.pl file2.csv
$ <file1.csv | perl this-script.pl file2.csv
$ ./this-script.pl file2.csv <file1.csv

または1行で:

$ perl -e 'while (<STDIN>) { $_ = <> if /^("")?$/; print }' <file1.csv file2.csv

関連情報