
20個の奇妙な列を持つCSVファイルがあります。
"VALUE1"
14列の値は、15列の値は14列と15列の値を取得する必要があります"VALUE2"
。
VALUE1
私の条件は、列14にあり、列15にある場合にのみ満たされますVALUE2
。総数を求める必要があります。
数のリストを提供し、14番目と15番目の列値を提供するwc -l
ことが可能であると思いました。しかし、14日と15日があることをcut -d "," -f14,15
どのように確認しますか?VALUE1
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
入力には,
区切り文字が含まれ、エスケープ文字は含まれていないと想定されます。,
テスト目的のために、列14と15の代わりに列2と3を使用してください。
パターンは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