약 15000개의 행과 여러 열이 있는 csv 파일이 있습니다. 데이터세트는 다음과 같습니다.
A,B,C, message D, E, F
a,b,c,Hi how are you ? d,e,f
a,b,c,Hi Hello.Are you ok? d,e,f
a,b,This >are< should not be counted,d,e,f
a,b,c,Hi I'm good. Are you ok ? d,e,f
a,b,c,Hi You are good, are you? d,e,f
a,b,c,I dare to add this line d,e,f
여기서 UNIX 쉘 명령을 사용하여 메시지 열에 "are"라는 단어의 발생 횟수를 어떻게 계산할 수 있습니까?
답변1
이 시도,
grep -oc are file
-o
일치하는 부분만 인쇄됩니다.-c
일치하는 줄의 개수를 인쇄합니다.
-i
결과도 필요한 경우 옵션을 추가할 수 있습니다 Are
. 일치하는 패턴의 대소문자 구분을 무시합니다.
같은 줄에 일치하는 패턴이 여러 개 있는 경우...
grep -o are file | wc -l
AWK 사용:
awk -F ',' '$4 ~ /are/ {count++} END{print count}' file
awk -F ',' '$4 ~ /[Aa]re/ {count++} END{print count}' file
답변2
이 문제를 해결하는 방법에는 두 가지가 있습니다.
sed -Ee '
y/,/\n/;s/\n/,/3;s//,/3;y/\n,/,\n/
s/.*\n(.*)\n.*/\1/;s/\<[aA][rR][eE]\>/\n/g
s/[^\n]*//g;/\n/!d;s///
' file.csv | wc -l
GNU sed
여기서는 확장 정규식 모드에서 및 를 사용합니다. 아이디어는 먼저 네 번째 필드를 분리한 다음 현재 패턴 공간에서 발견되는 모든 단어 "are"를 대소문자를 구분하지 않고 개행 문자로 변환하는 것입니다. 그런 다음 sed
표준 출력으로 인쇄될 때마다 자체 개행 문자를 넣는 대신 개행이 아닌 모든 항목을 제거하고 개행 문자를 제거합니다 . 그런 다음 출력 행 수를 계산하여 sed
각 행의 네 번째 필드에 있는 단어 "are"에 대해 대소문자를 구분하지 않는 모든 패턴의 합계를 제공합니다.
perl -F, -lane '
$k += split /(?<=\Ware)(?=\W)/i, $F[3];
}{print $k-$.;
' file.csv
Perl
네 번째 필드( $F[3]
)를 대소문자를 구분하지 않는 단어 "are" 주위로 분할합니다. 이는 "are"를 양쪽 끝에 \Ws로 묶어 결정됩니다. 그런 다음 분할 필드 수를 업데이트합니다. 필드는 항상 "are" 단어 수보다 1개 더 많아야 합니다.
마지막으로 모든 행을 읽고 처리한 후 kount에서 파일의 행 수를 뺀 값을 인쇄합니다.