我的 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 将匹配三个条件之一
- /\|\|/ 将匹配不是第一个或最后一个字段的任何空字段。
- /^\|/ 将匹配行开头的任何空字段 - “^”。
- /\|$/ 将匹配行末尾的任何空字段 - “$”。
由于 awk 识别 |作为运算符,当我们尝试匹配“|”时我们需要在它前面使用“\”。
现在,这 3 个条件用“||”串在一起awk 将其解释为“或”。然后,当这 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|