私のCSVファイルは次のとおりです(パイプ区切り)。
apple|banana|pear||grapefruit
lemon|lime|damson|jackfruit
|tangerine|nectarine|plum
apricot|orange|pineapple|coconut|
(さまざまなフィールドに存在できるすべての種類のスペースまたは特殊文字を想定します。)
最初の列と最後の列を含むすべての列の値が空であることを確認する必要があります。
予想出力:
apple|banana|pear||grapefruit
|tangerine|nectarine|plum
apricot|orange|pineapple|coconut|
どうすればいいですか?
答え1
〜のようにコメントに記載されている、単純で明確な答えはですが、grep '||'
最初または最後の列が空の場合はキャッチできません。
したがって、正解(まだ使用されているgrep
)は次のようになります。
grep '^|\|||\||$' file.txt
この文字は、バックスラッシュでエスケープしたり、このオプションを指定しない|
限り、Grepには特別な文字ではありません。-E
それでもこれは少し不明なので、ファイル内の区切り文字斑点:
grep '^,\|,,\|,$' file.txt
省略したい場合はそのまま含めてください最後フィールドは空ですが、他のフィールドは空の行を印刷します。最後の場合は省略してください。
grep '^|\|||' file.txt
実際、次のように各ケースを別々のパラメータに入れると、何が起こっているのかを簡単に確認できます。
grep -e '^|' -e '||' -e '|$' file.txt
答え2
最初のフィールドと最後のフィールドを含む空のフィールドを探します。
awk -F\| '{for(i=1;i<=NF;i++) if($i=="") { print $0; next } }' file.csv > out.txt
答え3
awkで試してみてください。一致する行番号を印刷します。
$ awk '/^\|/ || /\|\|/ || /\|$/{print $0}' input_test
apple|banana|pear||grapefruit
|tangerine|nectarine|plum
apricot|orange|pineapple|coconut|
元の質問に対する修正に基づいて、awkコマンドを再設計しました。
説明:awkは3つの条件のうちの1つと一致します。
- /\|\|/ は、最初または最後のフィールドではなく、すべての空のフィールドと一致します。
- /^\|/ は、行の先頭の空のフィールド ("^") と一致します。
- /\|$/ は行末の空のフィールド ("$") と一致します。
awk は | を演算子として認識するため、"|" を一致させるには、前に "\" を使用する必要があります。
この3つの条件は、awkが「or」と解釈する「||」と関連付けられます。その後、これら3つの条件のいずれかが一致すると、行全体が印刷されます。
特定の列を空にするように一致させるには、次のようにします。
awk -F"|" '!length($1) || !length($4) {print $0} ' input_test
答え4
使用ミラー:
$ cat pipe.dat
apple|banana||pear||grapefruit
lemon|lime|damson|jackfruit
|tangerine|nectarine|plum
apricot|orange|pineapple|coconut|
$ cat has-blanks.mlr
@has_empty = false;
for (k,v in $*) {
if (v == "") {
@has_empty = true;
break;
}
}
filter @has_empty;
$ cat pipe.dat | mlr --nidx --fs pipe put -f has-blanks.mlr
apple|banana||pear||grapefruit
|tangerine|nectarine|plum
apricot|orange|pineapple|coconut|