Bash에서는 첫 번째 csv 파일, 두 번째 csv 파일의 모든 행 및 세 번째 csv 파일에 답변을 요청해야 합니다.

Bash에서는 첫 번째 csv 파일, 두 번째 csv 파일의 모든 행 및 세 번째 csv 파일에 답변을 요청해야 합니다.

Bash에서는 첫 번째 csv 파일, 두 번째 csv 파일의 모든 행, 세 번째 csv 파일의 답변을 요청해야 합니다.

첫 번째 파일. 예를 들어 aaa.csv:

aaa
bbb
aaa
aaa
ccc
fff
aaa

두 번째 파일은 다음과 같습니다 bbb.csv.

aaa;111
bbb;222
ccc;333
ddd;444
eee;555
ggg;666

세 번째 파일은 다음과 같습니다 ccc.csv.

aaa;111
bbb;222
aaa;111
aaa;111
ccc;333
fff;
aaa;111

가능합니까? 이 틈에 잘못된 단어나 뭔가가 있을 수 있습니다. then을 사용하면 cat bbb.csv | grep -f aaa.csv > ccc.csv111에 aaa가 나타날 때만 부분적으로 공통이라고 대답합니다.aaa.csv

답변1

주석의 또 다른 가능한 접근 방식은 awk변경된 파일 순서를 사용할 수 있습니다.

awk -F';' 'FNR == NR { m[$1] = $2; next; } { if ($1 in m) { print $1 ";" m[$1]; } else { print $1 ";FALSE"; } }' bbb aaa

먼저 bbb 파일을 읽고 첫 번째 열의 키 값이 포함된 배열에 값을 저장한 다음 aaa 파일을 읽고 키가 배열에 있는지 확인하고 그에 따라 인쇄합니다.
결과:

aaa;111
bbb;222
aaa;111
aaa;111
ccc;333
fff;FALSE
aaa;111

답변2

다음을 수행할 수 있습니다.

while read linea
do
grep "$linea" bbb.csv >> ccc.csv || echo "$linea:FALSE" >> ccc.csv
done < aaa.csv

$ cat ccc.csv 
aaa;111 
bbb;222 
aaa;111 
aaa;111 
ccc;333 
fff:FALSE
aaa;111

답변3

메타 sed는 어떻습니까?

sed "$(sed 's^\(.*\);\(.*\)^s/\1/\1;\2/;tx^;$as/.*/&;FALSE/\n:x' bbb.csv)" aaa.csv

bbb.csv내부 sed 표현식은 다음 sed 프로그램으로 변환됩니다 .

s/aaa/aaa;111/;tx
s/bbb/bbb;222/;tx
s/ccc/ccc;333/;tx
s/ddd/ddd;444/;tx
s/eee/eee;555/;tx
s/ggg/ggg;666/;tx
s/.*/&;FALSE/
:x

그런 다음 외부 sed에 의해 해석되어 aaa.csv원하는 출력으로 변환됩니다.

aaa;111
bbb;222
aaa;111
aaa;111
ccc;333
fff;FALSE
aaa;111

tx생성된 sed 프로그램에 주의하세요 . x:이전 대체 항목이 일치하는 경우 s이는 sed 조건부 점프 라벨입니다 . 이렇게 하면 "FALSE" 텍스트를 대체하기 위해 끝에 포괄적인 문을 삽입할 수 있습니다.

bbb.csv이 답변에 대한 주의 사항은 생성된 전체 프로그램이 명령줄을 통해 전달되기 때문에 큰 파일로 확장되지 않는다는 것입니다 . 이것이 문제인 경우 생성된 프로그램을 임시 파일에 넣을 수 있습니다.

sed 's^\(.*\);\(.*\)^s/\1/\1;\2/;tx^;$as/.*/&;FALSE/\n:x' bbb.csv > bbb.tmp.sed
sed -f bbb.tmp.sed aaa.csv > ccc.csv

결과가 너무 커지면 여전히 제한적일 것입니다 bbb.tmp.sed. sed가 전체 파일을 메모리로 읽으려고 시도할 것이라고 생각합니다.

답변4

이 특정 스크립트를 작성하려면 쉘 도구보다는 Python을 사용하는 것이 좋습니다. 왜냐하면 Python의 표준 라이브러리에는 실제로 CSV 구문의 모든 문제를 처리할 수 있는 CSV 파서가 포함되어 있기 때문입니다. 당신은 다음과 같은 일을 할 것입니다 :

import csv
import sys

# sys.argv[1] = "aaa.csv", sys.argv[2] = "bbb.csv"
# sys.argv[3] = default value for mapping
# output written to stdout

with open(sys.argv[2], "rt") as f:
    rd = csv.reader(f, dialect="unix", delimiter=";")
    mapping = { row[0] : row[1] for row in rd }

with open(sys.argv[1], "rt") as f:
    rd = csv.reader(f, dialect="unix", delimiter=";")
    wr = csv.writer(sys.stdout, dialect="unix", delimiter=";",
                    quoting=csv.QUOTE_MINIMAL)

    for row in rd:
        wr.writerow([row[0], mapping.get(row[0], sys.argv[3])])

그런 다음 실행하십시오 python munge.py aaa.csv bbb.csv "" > ccc.csv.

일반적으로 쉘 스크립트에서 작업을 수행하는 방법이 명확하지 않은 경우 다음을 고려하십시오.쉘 스크립트에서는 이 작업을 수행하지 마십시오. 하드 설치에 대한 이식성이 보장되지 않는 한다른 것(예를 들어 Autoconf 매크로 내부) Perl, Python, Ruby, node.js 등을 작성하는 것이 더 편할 것입니다.

관련 정보