次のような形式の CSV ファイルがあります。
A @ B @ C @ D @ E
5 つの列が必要ですが、残念ながら最後の列が欠けているものもあります。
A @ B @ C @ D
@
最後の列が欠落しているすべての行の最後に余分なものを追加するにはどうすればよいですか?
スペースがフィールド コンテンツの一部であり、区切り文字が "@" のみであると仮定します (ただし、他のバリエーションにも簡単に対応できます)。
awk 'BEGIN {FS = OFS = "@"} {$5 = $5; print}' inputfile
AWK は、欠落している介在フィールドを作成します。フィールド値をそれ自体に設定すると、そのフィールドがすでに存在する場合、またはそのフィールドとその間に作成されたフィールドが空の文字列に設定されている場合、既存の内容が保持されます。
$ cat inputfile
A @ B @ C @ D @ E
A @ B @ C @ D
A @ B @ C
$ awk 'BEGIN {FS = OFS = "@"} {$5 = $5; print}' inputfile
A @ B @ C @ D @ E
A @ B @ C @ D @
A @ B @ C @@
これはあなたのために働くかもしれません:
sed 's/@/&/4;t;s/\s*$/ @/' file
テストされていませんが、次のようなものです:
perl -lpe '$n = tr/@/@/; $_ .= "@" x (4-$n)'
フィールドに@を含めることができず、フィールドが4つしかない場合にのみ置換を実行したい場合、これは実用的なsedソリューションである必要があります。
$ sed -r 's/^([^@]*[[:space:]]@){3}[^@]+$/& @/' <<EOF
> A @ B @ C @ D @ E
> A @ B @ C @ D
> EOF
A @ B @ C @ D @ E
A @ B @ C @ D @
GNUsedをsed -r
想定していることに注意してください。
ファイルで使用するために別のリダイレクトに置き換えます。
このようなものが機能する可能性があります:
cat foo.csv | sed -E "s/([^\@]+\@){3}([^\@]+)/&@/" | sed -E "s/\@\@/\@/"
これにより、foo.csvファイルが読み取られ、4番目の列の後に@が追加され、すでに1つある行の重複が削除されます。
Python を使用できる場合は、必要な数の @ を追加する、少しスマートなソリューションを次に示します。
from sys import *
for line in stdin.readlines():
stdout.write(line.strip())
if (line.count('@') < int(argv[1])):
stdout.write(' @' * (int(argv[1]) - line.count('@')))
stdout.write('\n')
次のように呼び出します。cat foo.csv | python fixcsv.py 4
awk -F'@' '{printf $0; if (NF == 4) {print "@"}}'
注: 入力A @ B @ C @ D
は出力になりますA @ B @ C @ D@
。意図的に 4 番目の値を変更せずに残しましたが、もちろん追加のスペースを追加することもできます