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.csv
111에 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 등을 작성하는 것이 더 편할 것입니다.