.csv 파일 읽기에 설정된 변수를 패턴으로 사용하여 두 번째 .csv 파일을 greping해 보세요.

.csv 파일 읽기에 설정된 변수를 패턴으로 사용하여 두 번째 .csv 파일을 greping해 보세요.

두 개의 .csv 파일이 있습니다. 첫 번째 파일에는 단어 목록이 있습니다. 두 번째 파일에는 두 개의 열이 있으며 첫 번째 열에는 첫 번째 파일의 항목과 일치하는 값이 포함됩니다. 첫 번째 파일을 한 줄씩 읽고 각 줄을 사용하여 두 번째 파일을 grep하고 싶습니다. 현재 코드 표시

  1. 행을 읽을 때
  2. 하다
  3. grep $line ./filetwo.csv
  4. <fileone.csv 완료

이 코드는 아무것도 생성하지 않습니다. $line을 파일을 읽어 할당되지 않은 변수로 바꾸면 완벽하게 작동합니다. 나는 수년 동안 이 문제를 연구해 왔지만 겉보기에 간단해 보이는 질문에 대한 답을 결코 찾지 못했습니다. .csv 파일을 읽어 할당된 변수가 직접 할당된 변수와 동일한 결과를 제공하지 않는 이유를 이해할 수 없습니다. zsh 쉘을 사용하고 있습니다.

답변1

CSV 파일은 Microsoft 세계에서 더 일반적이므로 다음을 찾을 수 있습니다.

  • 로캘의 문자 집합이 아닌 UTF-16으로 인코딩되므로 변환이 필요합니다.
  • 또는 UTF-8로 인코딩되지만 바이트 순서 표시가 있습니다.
  • CRLF 줄 구분 기호가 있습니다.
  • 마지막 줄은 분리되지 않습니다(따라서 readfalse가 반환됩니다).

이것이 사실인지 확인할 수 있습니다 file yourfile.csv.

그러면 다음과 같이 할 수 있습니다:

dos2unix < fileone.csv |
  while IFS=, read -r first rest_if_any_ignored; do
    dos2unix < filetwo.csv | grep -Fe "$first"
  done

(정규식 일치(in ) -F를 수행하는 기본값이 아닌 고정 문자열 검색에 유의하십시오 .) 그러나 이는 각 행에 대해 세 개의 명령을 실행하고 각 명령이 매번 처음부터 내용을 처리하기 때문에 상당히 비효율적입니다 .regrepfileone.csvgrepfiletwo.csv

$first또한 첫 번째 열뿐만 아니라 의 모든 위치에서 문자열을 찾고 filetwo.csv정확한 일치를 수행하지 않습니다. 예를 들어 $firstis 인 foo경우 foobar,otherother,foobar행이 보고됩니다. 이는 또한 CSV 참조를 처리하지 않습니다. 따라서 적절한 CSV 구문 분석 기능을 갖춘 언어를 사용하는 것이 좋습니다.

이러한 파일이 간단한 CSV, 즉 참조나 헤더가 없는 경우 다음 작업이 수행됩니다 join.

preprocess() {
  dos2unix -O -- "$@" | sort -t, -k1b,1
}

join -t, <(preprocess < fileone.csv) <(preprocess < filetwo.csv)

헤더와 가능한 따옴표(줄 바꿈이 포함된 데이터 포함)가 있는 실제 CSV의 mlr경우 CSV 파서를 사용할 수 있습니다.그것의 join동사.

foo예를 들어 첫 번째 열이 in fileone.csvbarin 으로 호출되는 경우 filetwo.csv:

mlr --csv join -j foo -r bar -f fileone.csv filetwo.csv

dos2unixCRLF, 무제한 라인 및 BOM이 있는 UTF-8을 처리할 수 있지만 UTF-16은 처리할 수 없습니다. 먼저 UTF-8을 사용하거나 UTF- 8 로 변환해야 합니다 iconv.

mlr간단한 CSV 및 기타 여러 테이블 형식도 수행할 수 있습니다. 자세한 내용은 해당 설명서를 참조하세요.

관련 정보