나는파일.csv
"ItemNo","Name","Weight"
"a001","Item a","1.1"
"a002","Item x","1.2"
"a003","Item_4","1.0"
"a004","Item b","1.1"
"a005","Itemb2","2.0"
"a006","a004","2.0"
몇 개 더 있어요프로젝트 번호.csv
"a003"
"a001"
"a004"
"ItemNo"와 연관된 "이름" 목록을 생성하는 명령을 찾고 있습니다...
그래서 나의출력.csv~해야 한다
"Item_4"
"Item a"
"Item b"
누구든지 도와줄 수 있나요?
첫 번째 열에 있는 file.csv의 각 item.no는 고유합니다. 하지만 a001, a001-b1, a001-b2 등이 있습니다. 하지만 "a001", "a001-b1"을 검색하면... 모든 것이 다시 고유해야 합니다.
특정 도구가 필요하지 않습니다. 모든 유용한 솔루션이 필요합니다. 하지만 첫 번째 행만 검색하면 좋을 것입니다(ItemNo "a006"(열 1)의 Item.Name이 "a004"(열 2)라고 가정).
나는 전에 시도했다grep 명령
grep -f itemno.csv file.csv | awk -F, '{print $2}'
하지만결과마지막 줄의 출력은 다음과 같습니다.
"Item b"
나는 전에 시도했다awk 명령
awk -F, 'NR==FNR{a[$1]; next} $1 in a{print $2}' itemno.csv file.csv
하지만결과마지막 줄의 출력은 다음과 같습니다.
"Item b"
어쩌면 명령을 반복하는 것이 더 나은 생각일까요?
그래서 나는 노력했다이번 사이클
while read -r line; do
grep "${line}" file.csv | awk -F "," '{print $2}';
done < itemno.csv
하지만 거기에는출력 없음...마치 각 줄 뒤에 다른 줄이 이어지는 것처럼\아르 자형
그래서 나는 노력했다이 명령
while read line; do
grep $(printf ${line} | sed 's/\r//g') file.csv | awk -F "," '{print $2}';
done < itemno2.csv
이것으로프로젝트 번호 2.csv
"a003"
"a001"
"a002"
"a004"
그리고산출예전에는 :
"Item a"
"Item x"
이 이상한 반복 명령을 통해서만 ItemNumber를 검색할 수 있습니다(그리고 명령은 첫 번째 행과 마지막 행을 무시합니다).
답변1
입력 데이터는 CSV 파일과 헤더 없는 CSV 파일입니다.
나중에 이름으로 포함하려는 필드를 참조할 수 있도록 헤더 없는 CSV 파일에 헤더를 추가하는 것부터 시작하세요 ItemNo
. 우리는 이것을 통해밀러( mlr
), untitled 모드를 사용하여 데이터를 읽은 --implicit-csv-header
다음 label
하위 명령을 사용하여 ItemNo
첫 번째 열에 레이블을 추가합니다.
$ mlr --csv --implicit-csv-header label ItemNo itemno.csv
ItemNo
a003
a001
a004
Miller를 사용하면 첫 번째 행에서 레이블을 선택하는 --implicit-csv-header
대신 내부적으로 첫 번째 필드에 레이블을 지정합니다 . 1
그런 다음 하위 명령은 label
이를 로 변경합니다 ItemNo
.
출력의 데이터가 인용되지 않았다는 사실은 인용할 필요가 없기 때문에 중요하지 않습니다(포함된 구분 기호나 개행 문자 등이 포함되지 않음). Miller는 인용이 필요한 필드를 자동으로 인용합니다.
join
그런 다음 Miller의 작업에 이를 사용할 수 있습니다 .
$ mlr --csv --implicit-csv-header label ItemNo itemno.csv | mlr --csv join -f file.csv -j ItemNo
ItemNo,Name,Weight
a003,Item_4,1.0
a001,Item a,1.1
a004,Item b,1.1
ItemNo
이는 입력 데이터 필드 file.csv
와 mlr
파이프라인의 첫 번째 명령 데이터 간에 관계형 "내부 조인" 작업을 수행합니다.
cut
그런 다음 추출된 필드에 대해 문자열 작업을 수행할 수 있습니다 Name
.
$ mlr --csv --implicit-csv-header label ItemNo itemno.csv | mlr --csv join -f file.csv -j ItemNo then cut -f Name
Name
Item_4
Item a
Item b
--headerless-csv-output
질문에 헤더 없는 CSV 출력을 얻을 수 있다는 점을 추가하고 , --quote-all
그렇게 할 필요가 없더라도 Miller가 모든 출력 필드를 인용하도록 강제할 수 있습니다.
$ mlr --csv --implicit-csv-header label ItemNo itemno.csv | mlr --csv --headerless-csv-output --quote-all join -f file.csv -j ItemNo then cut -f Name
"Item_4"
"Item a"
"Item b"
Miller는 입력 파일이 DOS인지 아니면 Unix 텍스트 파일인지 상관하지 않습니다. 복잡한 필드가 있는 CSV 파일을 구문 분석할 수 있습니다.
답변2
awk를 사용하십시오.
$ awk -F, '{sub(/\r$/,"")} NR==FNR{a[$1]; next} $1 in a{print $2}' itemno.csv file.csv
"Item a"
"Item_4"
"Item b"
DOS 줄 끝이 있다는 것을 알려주기 위해 질문을 업데이트했기 때문에 sub()
이것을 앞에 추가했습니다.
답변3
이제 나는 내 문제가 무엇인지 압니다.
이것프로젝트 번호.csv예전에는 :
"a003"\r
"a001"\r
"a004"
각 줄 끝에 \r이 없으면 다음 명령은
grep -f itemno.csv file.csv | awk -F, '{print $2}'
더 잘 일하고산출예
"Item_4"
"Item a"
"Item b"
"a004"
각 줄 끝에 \r이 없으면 다음 명령은
awk -F, 'NR==FNR{a[$1]; next} $1 in a{print $2}' itemno.csv file.csv
더 잘 일하고산출예
"Item_4"
"Item a"
"Item b"
각 줄 끝에 \r이 없으면 명령은 루프 명령입니다.
while read line; do
grep "${line}" file.csv | awk -F "," '{print $2}';
done < itemno.csv
이것을 감안할 때산출
"Item_4"
"Item a"
while read
명령이 마지막 줄을 읽지 않기 때문입니다 .