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