다음과 같은 CSV가 있습니다.
details.csv
1,2,3,4,5,2015-07-30 23:17:12,2015-07-30 23:39:12,103.4,104.2,1.2,"{1,2,3}",{NORMAL},1,2,
2,2,6,4,5,2015-07-30 12:17:12,2015-07-30 12:39:12,103.4,104.2,1.8,"{4,5,6,7,8,9}",{BOOKING},1,2,
3,2,3,4,9,2015-07-30 10:17:12,2015-07-30 10:39:12,103.4,104.2,1.9,"{1,9}","{NORMAL,BOOKING}",1,2,
여기서 열 15는 비어 있고 열 12는 단일 값인 경우 따옴표가 없습니다({예약}) 및 여러 값이 있는 경우 따옴표("{예약, 정상}").
여기에서 int 배열이고 고정된 크기가 없는 11개의 열을 삭제하고 싶습니다. 그래서 출력은 다음과 같습니다
mod_details.csv
1,2,3,4,5,2015-07-30 23:17:12,2015-07-30 23:39:12,103.4,104.2,1.2,{NORMAL},1,2,
2,2,6,4,5,2015-07-30 12:17:12,2015-07-30 12:39:12,103.4,104.2,1.8,{BOOKING},1,2,
3,2,3,4,9,2015-07-30 10:17:12,2015-07-30 10:39:12,103.4,104.2,1.9,"{NORMAL,BOOKING}",1,2,
그래서 나는 다음을 시도한다:
sed 's/,"{.*}"//' details.csv > mod_details.csv
하지만 문제는 내가 얻는 결과가
mod_details.csv
1,2,3,4,5,2015-07-30 23:17:12,2015-07-30 23:39:12,103.4,104.2,1.2,{NORMAL},1,2,
2,2,6,4,5,2015-07-30 12:17:12,2015-07-30 12:39:12,103.4,104.2,1.8,{BOOKING},1,2,
3,2,3,4,9,2015-07-30 10:17:12,2015-07-30 10:39:12,103.4,104.2,1.9,1,2,
또한 따옴표가 있기 때문에 값이 여러 개인 열 12 값도 제거합니다. 어떤 도움이라도 대단히 감사하겠습니다. 미리 감사드립니다.
답변1
사실 특별히 어렵지는 않습니다. 다음보다 더 구체적인 패턴을 사용해야 합니다 {.*}
.
sed 's/"{\([0-9],\)\+[0-9]}",//' details.csv
답변2
답을 찾는 단계로서 다음 셸 기능이 도움이 될 수 있습니다. 명령줄에서 멋진 "예쁜" 레이아웃으로 CSV를 보기 위해 작성했습니다.
그것에주의를 기울이십시오삭제따옴표로 묶인 쉼표와 따옴표로 묶인 줄 바꿈(및 따옴표로 묶은 큰 따옴표)은 아마도 원하는 것이 아닐 수도 있지만 열을 빠르게 확인하고 올바르게 정렬하는 데 유용합니다.
excel() {
sed -E -e ':t' -e '/^[^"]*("[^"]*"[^"]*)*$/!{N;s/\n//;bt' -e'}' "$@" |
awk -F\" -v OFS= 'NF>1 {for (i=2;i<=NF;i+=2) gsub(/,/, "", $i)} 1' |
sed 's/,/,"/g' | column -ts, | tr -d '"' | less -S
}
답변3
사용csvkit
:
$ csvcut -C 11 details.csv
1,2,3,4,5,2015-07-30 23:17:12,2015-07-30 23:39:12,103.4,104.2,1.2,{NORMAL},1,2,
2,2,6,4,5,2015-07-30 12:17:12,2015-07-30 12:39:12,103.4,104.2,1.8,{BOOKING},1,2,
3,2,3,4,9,2015-07-30 10:17:12,2015-07-30 10:39:12,103.4,104.2,1.9,"{NORMAL,BOOKING}",1,2,
답변4
각 행을 "
구분 기호로 배열로 분할하는 것이 더 쉬운 방법입니다. 그러면 int 배열은 배열의 요소 1이 되며, 이를 빈 문자열로 설정할 수 있고, 다음 요소(요소 2)에는 끝에 추가 쉼표가 추가되므로 다음에서 시작 부분 문자열을 추출할 수 있습니다. 두 번째 캐릭터가 시작됩니다. 이제 {NORMAL,BOOKING}
어떻게든 해당 섹션에 큰따옴표를 반환하는 작업을 처리 해야 합니다 . 분할선을 "
구분 기호로 사용하면 행에 필드 3이 있으므로 이 부분도 처리됩니다. 다른 행이라면 더 이상 따옴표가 없으므로 항목 배열에는 인덱스 2 이전의 항목만 포함됩니다. 인덱스 #3이 있으면 이를 참조해야 한다는 것을 알고 있습니다.
Perl의 다음 한 줄은 위에서 설명한 것과 정확히 동일한 작업을 수행합니다.
$ perl -F'"' -lane '$F[1]="";$F[2]=substr($F[2],1);$F[3]= "\"" . $F[3] . "\"" if $F[3];print @F' inpu>
1,2,3,4,5,2015-07-30 23:17:12,2015-07-30 23:39:12,103.4,104.2,1.2,{NORMAL},1,2,
2,2,6,4,5,2015-07-30 12:17:12,2015-07-30 12:39:12,103.4,104.2,1.8,{BOOKING},1,2,
3,2,3,4,9,2015-07-30 10:17:12,2015-07-30 10:39:12,103.4,104.2,1.9,"{NORMAL,BOOKING}",1,2,