空の列に文字列を挿入する

空の列に文字列を挿入する

空の列にテキストを挿入しようとしています。ファイルはタブで区切られ、空の列にテキストを挿入しようとしています。例えば

Column1  Column2  Column3
string1  decs1    1234
         desc1    1255
string3           3443
string4  desc1    1
string5           435

空の列1または2にNULLというテキストのみを挿入しようとしています。だからこんな感じです。 (2列が空の場合、1列と3列の間にダブルタップがあります。)

column1  column2  column3
string1  decs1    1234
null     desc1    1255
string3  null     3443
string4  desc1    1
string5  null     435

試してみましたがawk、テストではすべての列2にNULLテキストを挿入しますが、空の項目がある場合は3番目の列を列2に切り捨てます。

awk '{sub("$", "NULL", $2)}; 1' file.txt > file2.txt

結果はこれです

column1  column2 column3
string1  desc1NULL 1234
string2  desc1NULL 1255
string3  3443NULL
string4  descNULL  1
string4  435NULL

明らかに間違った構文を使用していますが、修正する方法がわかりません。

ありがとう

答え1

私はこれを行うことをお勧めしますsed

sed -E -e :1 -e 's/(^|\t)(\t|$)/\1null\2/;t1' yourfile

(移植性のために実際のTAB文字を代わりに使用してください\t。ただし、ブラウザのコピー/貼り付け以降は保持されないことがあります。)

空のフィールドを検出する方法は?どちらか

  • ^\t行の先頭のタブ文字()または
  • \t\t2つのタブ()の間には何もありません。または
  • \t$行の末尾にタブ文字()があります。

これらすべての場合で、s2 つの一致の間のパターンを置き換えます。

2つの空のフィールドが順番にある場合はループを実行する必要があるため、何かが置き換えられたらマーカーにt1ジャンプします。:1

答え2

awk -F'\t' -v OFS='\t' '$1==""{ $1="NUll" }  $2==""{ $2="NUll" }1' infile

そしてsub("$", "NULL", $2)$、2番目の列の文字列の末尾を$2"NULL"文字列に置き換えるためにsub()関数を呼び出しています。また、これらの列は空の場合にのみ「NULL」に置き換えられます。 sub() を使用すると、次のことができます。

awk -F'\t' -v OFS='\t' '
  $1==""{ sub(/.*/, "NULL", $1) }
  $2==""{ sub(/.*/, "NULL", $2) }
  $3=="" { "......" }
  # etc ...
1' infile

または:

awk -F'\t' -v OFS='\t' '
  { sub(/.*/, ($1==""?"NULL":$1), $1) }
  { sub(/.*/, ($2==""?"NULL":$2), $2) }
  # continue ...
1' infile

...しかし、これは前の最初のコマンドよりも少し悪いです。あるいは、交換操作が2つの列に限定されず、次のような場合でも、次のバリアントを使用できます。窒素リスト。

awk -F'\t' -v OFS='\t' -v N=2 '{
  while(colNr++<N){
      $colNr=($colNr==""?"NULL":$colNr)
  }
  colNr=0
}1' infile

答え3

すべてのUnixシステムのすべてのシェルでawkを使用してください。

$ awk 'BEGIN{FS=OFS="\t"} {for (i=1; i<=NF; i++) if ($i=="") $i="null"} 1' file
Column1 Column2 Column3
string1 decs1   1234
null    desc1   1255
string3 null    3443
string4 desc1   1
string5 null    435

sを使用すると、sub()次のようになります。

$ awk '{ while(sub(/\t\t/,"\tnull\t")); sub(/^\t/,"null\t"); sub(/\t$/,"\tnull")}1' file
Column1 Column2 Column3
string1 decs1   1234
null    desc1   1255
string3 null    3443
string4 desc1   1
string5 null    435

答え4

csvkitツールを使用して、存在しないすべての値を文字列で置き換えて修正した中間JSON文書を作成し、変更されたNULLJSON文書をタブ区切りのCSVに変換します。

csvjson -t file |
jq '.[] |= map_values(. // "NULL")' |
in2csv --blanks -f json | csvformat -T

ここでは、csvjson -t最初にというファイルからタブ区切りの入力を解析してfileJSONを出力します。次に、jq生成された文書を変更するために呼び出し、すべてのnull値を文字列に置き換えますNULL。この呼び出しは、JSON文書を読み取り、文字列をNULL値に置き換えることを防ぐin2csvためにCSVを生成します。最後に、Reformat CSV data to be tab-delimitedを使用します。--blanksNULLcsvformat -T


同様ですが、jqデータセット全体の配列を読み取ることなく個々の行のストリームを処理できます。その後、データはin2csv

csvjson --stream -t file |
jq -c 'map_values(. // "NULL")' |
in2csv -f ndjson --blanks | csvformat -T

関連情報