私は、例えば20の奇数列を持つcsvファイルを持っています。
14番目と15番目の列の値を取得する必要があります。14番目の列の値は"VALUE1"
で、15番目の列の値は"VALUE2"
です。
14番目の列にVALUE1
があり、15番目の列にVALUE2
がある場合にのみ、条件が満たされます。集計数を取得する必要があります。
wc -l
はカウントリストを提供し、cut -d "," -f14,15
は14番目と15番目の列の値を提供すると思います。しかし、14日にはVALUE1
があり、15日にはVALUE2
があるかどうかを確認する方法は?
以下のものはうまくいくと思います
grep -r "" * | cut -d " " -f14,15 | grep "Value1" | grep "Value2"
それでも、これが完璧な方法だとは思いません。
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}'
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"
からの質問は、指定したことを行いません-一致しすぎます。例:
...、Value1Value2 、、 ... ...、Value1、Value2、... ...、OtherValue1、Value2、... ...
awk
が使用可能な場合(かなり標準的なものです)、次のように実行できます。
$ echo -e 'a,b, c,d\na,val1,val2,c' \
| awk -F, '$2 == "val1" && $3 == "val2" {++sum} END {print sum}'
awk
は、値から空白を自動的に削除します。 END
は、すべての行が処理された後に一致する特別なパターンです。
次の関数はBashのみを使用して、必要な処理を実行します。
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