私はこの質問に対する答えを探していましたが、近づきましたが、十分に近づいていませんでした。何も変更せずに「NULL」テキストを含むCSVファイルを受け取ります。例:
- 入力する
12345,George,MCNULLMAN,NULL,green,NULL
- 交換結果は次のとおりです。
12345,George,MCNULLMAN,,green,
私はこれをテストしようとしましたが、単語の境界ではカンマを考慮しないようです。
echo "MCNULLMAN,HELLO,NULL,NULL" | sed 's|bNULL/b||g'
途中で人を含む名前をsed 's|NULL||g'
受け取るまで、しばらくうまくいきました。NULL
どんな提案がありますか?
答え1
表形式のデータを扱うときは、次のことをお勧めしますawk
。
awk 'BEGIN{FS=OFS=","}{for (i=1;i<=NF;i++) if ($i=="NULL") $i=""}1' input.csv
これにより、入力フィールドと出力フィールドの区切り文字がに設定されます,
。その後、行のすべてのフィールドを繰り返し、NULL
まったく同じ場合は空の文字列に置き換えます。すべての修正を含む行を印刷するように指示します(存在する場合)1
。awk
必要に応じて、sed
フィールド区切り文字をハードコーディングすることをお勧めします(行の先頭に先行するコンマを許可し、行の末尾に末尾のコンマを許可する)。
sed -E 's/(^|,)(NULL)(,|$)/\1\3/g' input.csv
これは、キャプチャグループを利用して、前のフィールドと次のフィールドの区切り文字(変更されているフィールドに応じてコンマまたは行の開始/終了になる可能性があります)の実際の値を記録し、全体の「前 - 区切り記号+フィールド+末尾-」を置き換えます。区切り記号" "前の区切り記号+末尾の区切り記号"にのみ結合されます。
参考にしてくださいこれは、引用しない「簡単なCSV」ファイルにのみ適用されますNULL
。
答え2
使用ミラー(mlr
)は、NULL
ヘッダーなしのCSV入力ファイルの正確な文字列のすべてのフィールドを消去します。
$ cat file.csv
12345,George,MCNULLMAN,NULL,green,NULL
$ mlr --csv -N put 'for (k,v in $*) { v == "NULL" { $[k] = "" } }' file.csv
12345,George,MCNULLMAN,,green,
これは、複雑な参照を含むCSVファイルにも当てはまります。
$ cat file.csv
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL","NULL",green,"""NULL"""
$ mlr --csv -N put 'for (k,v in $*) { v == "NULL" { $[k] = "" } }' file.csv
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL",,green,"""NULL"""
上記のサンプルレコードには、文字列のみを含むフィールドが1つありますがNULL
、4番目のフィールド(前green
)です。また、不要な引用符のセットも含まれています。 (最後のフィールドは"NULL"
リテラル引用符を含むため消去されません。2行目NULL
の最初のフィールドはリテラル改行を含む最初のフィールドの一部です。同様に、NULL,NULL
値を持つフィールドはタッチされません。)
答え3
使用awk
:
awk '{sub(/^NULL,/, ",");
gsub(/,NULL,/, ",,");
sub(/,NULL$/, ",")}1' file
使用csvsql
:
file.csvを単純なCSVファイルとして使用します。
12345,George,MCNULLMAN,NULL,green,NULL
$ csvsql -H -I --query 'select * from file' file.csv | csvformat -K 1
12345,George,MCNULLMAN,,green,
複雑な参照を含むfile.csv。
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL","NULL",green,"""NULL"""
$ csvsql -H -I --query 'select * from file' file.csv | csvformat -K 1
12345,"George
NULL,MacGregor",MCNULLMAN,"NULL,NULL",,green,"""NULL"""
-H
のための--no-header-row
。-I
のための--no-inference
。このオプションがないと、コマンドは12345
に変わります12345.0
。-K n
のための--skip-lines
。まずスキップNワイヤー。
csvsql -H
このコマンドはヘッダー行を追加するために使用されます。- K 1
削除してください。
答え4
使用幸せ(以前のPerl_6)
~$ raku -ne '.split(",").map(*.subst: :global, /^NULL$/ ).join(",").put;' file
または
~$ raku -ne '.split(",")>>.subst( :global, /^NULL$/ ).join(",").put;' file
上記は、Perlシリーズのプログラミング言語であるRakuで書かれた答えです。自動印刷ではなく、1行ずつフラグを使用してファイルを1行ずつ読みます-ne
。これらのフラグは Raku に各フラグ行の後にコードを実行するよう指示します。
入力データ(行など)は、Rakuの$_
テーマ変数にロードされます。ここでは、テキストは$_.split
カンマで始まります(上記の注:先行を削除し$_
て書き込むことができます.split
)。
次に、結果要素を繰り返してmap
各subst
要素にメソッドを適用します。ここでは、間に何もせずに/^NULL$/
始まり、終わる要素に一致するすべての項目が何もないものに置き換えられます(副詞/引数は重複しますが、他の場合は便利です)。NULL
:global
最後に変更された要素は、join
カンマとアウトを使用してグループ化されますput
。
入力例:
12345,George,MCNULLMAN,NULL,green,NULL
12345,George,MCNULLMAN,NULL,green,nail
NULL,George,MCNULLMAN,NULL,green,neal
出力例:
12345,George,MCNULLMAN,,green,
12345,George,MCNULLMAN,,green,nail
,George,MCNULLMAN,,green,neal