我有一个 csv 文件,其中有 20 个奇数列。
我需要获取第 14 列和第 15 列值,其中第 14 列中的值为 say "VALUE1"
,第 15 列中的值为"VALUE2"
。
VALUE1
仅当第 14 列有且第 15 列有时,我的条件才满足VALUE2
。我需要得到总数。
我认为wc -l
可以给我计数列表并
cut -d "," -f14,15
给我第 14 和 15 列值。但是如何检查第 14 个VALUE1
和第 15 个是否有VALUE2
呢?
我认为下面的有效
grep -r "" * | cut -d " " -f14,15 | grep "Value1" | grep "Value2"
但我仍然认为这不是完美的方法。
答案1
awk
在这里可能更有用。
例如:
$> echo "a b c d e" | awk '$2=="b" && $3=="c" {print}'
a b c d e
$> echo "a b c d e" | awk '$2=="a" && $3=="c" {print}'
$> echo "a b c d e" | awk '$2=="b" && $3=="d" {print}'
所以你的问题的答案可能是:
awk '$14=="VALUE1" && $15=="VALUE2" {print}'
答案2
如果awk
不可用,您可以使用cut
,grep
和 来完成wc
:
$ echo -e 'a,b, c,d\na,val1 ,val2,c' \
| cut -d ',' -f2,3 | grep '^ *val1 *, *val2 *$' | wc -l
假设输入中,
包含分隔符(并且不包含任何转义符)。,
出于测试目的,使用第 2 列和第 3 列而不是第 14 列和第 15 列。
请注意,该grep
模式允许在值之前/之后添加尾随空格(*
如果您不希望这样做,可以删除子模式)。元字符^
和$
匹配行的开头和结尾。
您问题中的管道grep "Value1" | grep "Value2"
不执行您指定的操作 - 它会匹配太多,例如:
..., 值 1 值 2, , ... ...、值 1、值 2、... ...、其他值 1、值 2、... ...
如果awk
可用(这是相当标准的),你可以这样做:
$ echo -e 'a,b, c,d\na,val1,val2,c' \
| awk -F, '$2 == "val1" && $3 == "val2" {++sum} END {print sum}'
awk
自动修剪值中的空格。END
是一种特殊模式,在处理完所有行后进行匹配。
答案3
以下函数将仅使用重击做你想做的事:
foo ()
{
local filename="$1";
while IFS=, read -ra arr; do
if [[ "${arr[13]}" = "VALUE1" && "${arr[14]}" = "VALUE2" ]]; then
printf '%s\n' "${arr[13]}" "${arr[14]}";
fi;
done < "$filename"
}
用法:foo [/path/to/file.txt]
示例输出:
rany$ cat > source.txt
a,a,a,a,a,a,a,a,a,a,a,a,a,VALUE1,VALUE2
a,a,a,a,a,a,a,a,a,a,a,a,a,NOMATCH1,NOMATCH2
a,a,a,a,a,a,a,a,a,a,a,a,a,VALUE1,VALUE2
rany$ foo source.txt
VALUE1
VALUE2
VALUE1
VALUE2