csv 파일을 바꾸는 명령 줄 유틸리티가 있습니까?


16

이렇게 파일이 주어지면

First,Last,Age
Cory,Klein,27
John Jacob,Smith,30

내용을 바꾸는 명령 줄 유틸리티가 있습니까?

First,Cory,John Jacob
Last,Klein,Smith
Age,27,30

답변:


6
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv

이 대답은 '훨씬 더 간결 질보다) A : 내이 허용으로이로 변경 정당화 할이 질문의 나이를 감안하지 python) B, ruby이하 휴대용 더되어 python이 또한 쇼는 어떻게 입력 / 출력을 전달하는) 및 C 파일. Bravo @luikore, Unix & Linux에 오신 것을 환영합니다. 주위에 붙어주세요.
코리 클라인

csv에서 한 가지 경고는 필드를 인용해야합니다
yosefrow

@yosefrow 인용 할 필요가 없습니다. 이 답변을 게시하기 전에 명령을 테스트했습니다.
luikore

그래, 그때 "may"라고 말했을 것입니다. 모든 필드를 인용하기 전까지는 효과가 없었습니다. 내 데이터 내용과 관련이있을 수 있습니다
yosefrow

16

따옴표없이 간단한 CSV 변형을 사용하지 않으면 필드에 쉼표가 표시되지 않는 한 POSIX 도구만으로는 CSV 구문 분석이 쉽게 수행되지 않습니다. 그럼에도 불구 하고이 작업은 awk 또는 다른 텍스트 처리 도구로 수행하기가 쉽지 않습니다. Perl with Text::CSV, Python with csv, R with read.csv, Ruby with CSV ,… 와 함께 사용할 수 있습니다 (이 모든 것은 Perl을 제외한 각 언어의 표준 라이브러리의 일부입니다).

예를 들어, 파이썬에서 :

import csv, sys
rows = list(csv.reader(sys.stdin))
writer = csv.writer(sys.stdout)
for col in xrange(0, len(rows[0])):
    writer.writerow([row[col] for row in rows])


3

빠르고 더러운 솔루션 :

c=1
file=file.txt
num_lines=$(wc -l < "$file")

for ((i=0; i<num_lines; i++)) {
    cut -d, -f$c "$file" | paste -sd ','
    ((c++))
}

/ tmp / l는 무엇을 나타 냅니까? 또한, for ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
선보다

이것은 OP의 입력에서 작동하지만 데이터의 행과 열 수가 동일하기 때문에 작동하지만 일반적으로 그렇지 않습니다.
tokland

CSV는 dpuble 따옴표에 대한 사양을 가지고, 즉 this "is" example셀은 인코딩 "this ""is"" example"나는 확신하고 있지 않다 제대로이 솔루션은 핸들 이러한 경우를 경우
그르 Wierzowiecki

0

제안 된 제한 (인용 부호 없음, 포함 된 쉼표 없음)을 감안할 때, awk에서 간단합니다 (perl은 2,000 줄 이상 CSV.pm, 2300 줄 이상을 고려하지 않기 때문에 csv.rb-python은 450 줄만 있음 csv.py)

다음은 awk의 예입니다.

#!/usr/bin/awk -f
BEGIN { width=0; }
{
    max = split($0, list, ",");
    # printf "%d:%s\n", NR, $0;
    if (width < max)
        width = max;
    for (n = 1; n <= max; ++n) {
        sub("^[     ]*","",list[n]);
        sub("[  ]*$","",list[n]);
        # printf "\t%d:%s\n", n, list[n];
        if ( columns[n] != "" ) {
            columns[n] = columns[n] ", ";
        }
        columns[n] = columns[n] list[n];
    }
}
END {
    # printf "%d columns\n", width;
    for (n = 1; n <= width; ++n) {
        printf "%s\n", columns[n];
    }
}

그건 그렇고 : 주어진 예에는 OP가 제거 될 것으로 예상되는 여분의 공간이 있습니다. 다른 예는이 세부 사항을 다루지 않았습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.