csv 파일이있는 경우 단일 열의 내용 만 인쇄하는 빠른 bash 방법이 있습니까? 각 행에 동일한 수의 열이 있다고 가정하는 것이 안전하지만 각 열의 내용은 길이가 다릅니다.
답변
이를 위해 awk를 사용할 수 있습니다. ‘$ 2’를 원하는 n 번째 열로 변경합니다.
awk -F "\"*,\"*" '{print $2}' textfile.csv
답변
예. cat mycsv.csv | cut -d ',' -f3
세 번째 열을 인쇄합니다.
답변
이 작업을 수행 할 수있는 가장 간단한 방법은 csvtool을 사용하는 것 입니다. csvtool을 사용하는 다른 사용 사례도 있었으며 열 데이터 자체에 나타나는 경우 따옴표 또는 구분 기호를 적절하게 처리 할 수 있습니다.
csvtool format '%(2)\n' input.csv
2를 열 번호로 바꾸면 찾고있는 열 데이터가 효과적으로 추출됩니다.
답변
탭으로 구분 된 파일에서 추출하기 위해 여기에 도착했습니다. 내가 추가 할 것이라고 생각했다.
cat textfile.tsv | cut -f2 -s
여기서 -f2
0이 아닌 인덱스 열 또는 두 번째 열을 추출합니다.
답변
이 질문에 대한 많은 답변은 훌륭하며 일부는 코너 케이스를 조사했습니다. 일상적으로 사용할 수있는 간단한 답변을 추가하고 싶습니다 … 대부분 그 코너 케이스에 들어가는 경우 (예 : 쉼표 나 쉼표를 따옴표로 이스케이프 처리).
FS (Field Separator)는 값이 공백으로 손상되는 변수입니다. 따라서 기본적으로 awk는 모든 줄의 공간에서 분할됩니다.
따라서 BEGIN (입력하기 전에 실행)을 사용하여이 필드를 원하는대로 설정할 수 있습니다.
awk 'BEGIN {FS = ","}; {print $3}'
위의 코드는 csv 파일의 세 번째 열을 인쇄합니다.
답변
다른 답변은 잘 작동하지만 bash 셸을 사용하여 솔루션을 요청했기 때문에 다음과 같이 할 수 있습니다.
AirBoxOmega:~ d$ cat > file #First we'll create a basic CSV
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
a,b,c,d,e,f,g,h,i,k
1,2,3,4,5,6,7,8,9,10
그런 다음 다음과 같이 열 (이 예의 첫 번째)을 꺼낼 수 있습니다.
AirBoxOmega:~ d$ while IFS=, read -a csv_line;do echo "${csv_line[0]}";done < file
a
1
a
1
a
1
a
1
a
1
a
1
여기에 몇 가지 일이 있습니다.
-
while IFS=,
-이것은 쉼표를 IFS (Internal Field Separator)로 사용하는 것입니다. 쉘이 필드 (텍스트 블록)를 구분하는 것을 알기 위해 사용하는 것입니다. 따라서 IFS =라고 말하는 것은 “a, b”가 “a b”와 동일하다고 말하는 것과 같습니다. IFS = “”(기본값) 인 경우입니다. -
read -a csv_line;
-이것은 한 번에 하나씩 각 줄을 읽고 각 요소를 “csv_line”이라고하는 배열을 만든 다음 while 루프의 “do”섹션으로 보냅니다. -
do echo "${csv_line[0]}";done < file
-이제 우리는 “do”단계에 있으며 “csv_line”배열의 0 번째 요소를 echo합니다. 이 작업은 파일의 모든 줄에서 반복됩니다.< file
부분은 어디에서 읽을 수있는 while 루프를 말하고있다. 참고 : bash에서 배열은 인덱스가 0이므로 첫 번째 열은 0 번째 요소입니다.
그래서 거기에 쉘의 CSV에서 열을 가져옵니다. 다른 솔루션은 아마도 더 실용적 일 수 있지만 이것은 순수한 bash입니다.
답변
GNU Awk를 사용할 수 있습니다 . 이 사용자 가이드 문서를 참조하십시오 . 기사 (2015 년 6 월)에 제시된 솔루션의 개선으로, 다음 gawk 명령은 큰 따옴표 필드 안에 큰 따옴표를 허용합니다. 큰 따옴표는 두 개의 연속적인 큰 따옴표 ( “”)로 표시됩니다. 또한 이것은 빈 필드를 허용 하지만 이것조차도 여러 줄 필드를 처리 할 수 없습니다 . 다음 예제 c=3
는 textfile.csv 의 세 번째 열 (를 통해 )을 인쇄합니다 .
#!/bin/bash
gawk -- '
BEGIN{
FPAT="([^,\"]*)|(\"((\"\")*[^\"]*)*\")"
}
{
if (substr($c, 1, 1) == "\"") {
$c = substr($c, 2, length($c) - 2) # Get the text within the two quotes
gsub("\"\"", "\"", $c) # Normalize double quotes
}
print $c
}
' c=3 < <(dos2unix <textfile.csv)
의 사용을주의 dos2unix
“\ n”와 UTF-8 (바이트 순서 표시가없는) 각각에 가능한 DOS 스타일의 줄 바꿈을 변환 할 (CRLF 즉 “\ 연구 \ n”) 및 (바이트 순서 마크) UTF-16 인코딩을. 표준 CSV 파일은 CRLF를 줄 바꿈으로 사용 합니다. Wikipedia를 참조하십시오 .
입력에 여러 줄 필드가 포함될 수있는 경우 다음 스크립트를 사용할 수 있습니다. 출력에서 레코드를 분리하기 위해 특수 문자열을 사용하는 것에 유의하십시오 (기본 분리 자 개행이 레코드 내에서 발생할 수 있기 때문입니다). 다시, 다음 예제 c=3
는 textfile.csv 의 세 번째 열 (을 통해 )을 인쇄합니다 .
#!/bin/bash
gawk -- '
BEGIN{
RS="\0" # Read the whole input file as one record;
# assume there is no null character in input.
FS="" # Suppose this setting eases internal splitting work.
ORS="\n####\n" # Use a special output separator to show borders of a record.
}
{
nof=patsplit($0, a, /([^,"\n]*)|("(("")*[^"]*)*")/, seps)
field=0;
for (i=1; i<=nof; i++){
field++
if (field==c) {
if (substr(a[i], 1, 1) == "\"") {
a[i] = substr(a[i], 2, length(a[i]) - 2) # Get the text within
# the two quotes.
gsub(/""/, "\"", a[i]) # Normalize double quotes.
}
print a[i]
}
if (seps[i]!=",") field=0
}
}
' c=3 < <(dos2unix <textfile.csv)
문제에 대한 또 다른 접근 방식이 있습니다. csvquote 는 일반적인 Unix 텍스트 처리 도구를 사용하여 특정 열을 선택할 수 있도록 필드 내의 특수 문자가 변환되도록 수정 된 CSV 파일의 내용을 출력 할 수 있습니다. 예를 들어 다음 코드는 세 번째 열을 출력합니다.
csvquote textfile.csv | cut -d ',' -f 3 | csvquote -u
csvquote
임의의 큰 파일을 처리하는 데 사용할 수 있습니다.