CSV에서 특정 범위의 행만 추출(및 stdout으로 덤프)하시겠습니까?

CSV에서 특정 범위의 행만 추출(및 stdout으로 덤프)하시겠습니까?

행이 약 1000개 있는 CSV 파일이 있는데 이를 가져오려는 시점에 700행에서 오류가 발생합니다. 그러나 이 CSV의 항목에는 개행 문자가 포함되어 있고 인용되어 있으므로 awkQuick 등을 사용하는 행 700을 실제로 표시할 수는 없습니다 .

그래서 내가 찾았어csv 파일을 처리하는 강력한 명령줄 도구가 있습니까?csvfix, 둘 다 설치 되어 있지만 csvkit이러한 응용 프로그램 중 어느 것도 단순히 줄 번호(또는 줄 범위)를 지정하고 출력하는 것을 지원하지 않는 것 같습니다. 예를 들어:

$ csvfix help echo
echo input CSV data to output
usage: csvfix echo [flags] [file ...]
where flags are:
  -ibl      ignore blank input lines
  -sep s    specify CSV field separator character
  -rsep s   as for -sep but retain separator on output
  -osep s   specifies output separator
  -hdr s    write the string s out as a header record
  -ifn      ignore field name record
  -smq      use smart quotes on output
  -sqf fields   specify fields that must be quoted
  -o file   write output to file rather than standard output
  -skip t   if test t is true, do not process or output record

echo에코할 라인을 지정할 수 있는 한 이것이 나에게 필요한 전부라고 생각했을 것입니다 . 그러나 내가 볼 때http://neilb.bitbucket.org/csvfix/manual/csvfix16/csvfix.html?unique.html, 열만 설명합니다.

이러한 도구(또는 다른 도구)를 사용하여 1000행 CSV의 700행(또는 702-705행)을 표준 출력으로 간단히 덤프하려면 어떻게 해야 합니까?


편집: 발견됨(http://neilb.bitbucket.org/csvfix/manual/csvfix16/ExpressionLanguage.html) csvfix가지다:

csvfix find -if '$line == 407' data.csv

...그러나 이는 실제로 줄 번호가 아니라 줄 번호입니다. 따라서 줄이 406번 줄에서 시작하여 407번 줄로 바뀌고 407번 줄에서 끝나는 경우 위 명령은 아무것도 출력하지 않습니다. 행이 있으면 -if '$line == 406'해당 행이 덤프됩니다. 이것도 유용하지만 여전히 줄 번호는 아닙니다 ...

답변1

csvfix find명령은 범위 또는 숫자별로 행 덤프를 지원합니다. 다음 명령은 file.csv라는 파일에서 3행과 4행을 추출합니다.

csvfix find -if '$line >= 3 && $line < 5' file.csv

답변2

일반 텍스트 도구를 사용하고 줄 바꿈을 다시 추가할 수 있도록 인용된 모든 줄 바꿈을 일시적으로 제거할 수 있습니다.

예를 들어, 큰따옴표의 경우:

gawk -v RS='"' 'NR % 2 == 0 { gsub(/\n/, "%NEWLINE%") } { printf("%s%s", $0, RT) }' file.csv > tmp.csv
head -n 700 tmp.csv | sed 's/%NEWLINE%/\n/g' > file_1-700.csv

답변3

다음과 같이 Perl의 Text::CSV_XS에서 위치를 얻을 수 있습니다.

perl -MText::CSV_XS -E 'open(my $fh, "<:encoding(utf8)", $ARGV[0]) or die "open: $!"; $csv = Text::CSV_XS->new({binary => 1, auto_diag => 9, diag_verbose => 1 } ); while (my $row = $csv->getline($fh)) { say tell $fh }' FILENAME.csv

FILENAME.csv끝에 .

각 줄을 성공적으로 구문 분석한 후 인쇄됩니다.바이트오프셋.

한 줄의 압축을 푼다:

use Text::CSV_XS;
use feature 'say';
open(my $fh, '<:encoding(utf8)', $ARGV[0]) or die "open: $!";
$csv = 'Text::CSV_XS'->new({'binary' => 1, 'auto_diag' => 9, 'diag_verbose' => 1});
while (my $row = $csv->getline($fh)) {
    say tell $fh
}

나는 이 CSS( )를 잘못 지정했습니다 new.css.

r1c1,"r1
c2",r1c3
r2c1,"r2c2,r2c3
r3c1,r3c2,r3c3

산출:

18
# CSV_XS ERROR: 2027 - EIQ - Quoted field not terminated @ rec 1 pos 15 field 2

(손상된 행 앞에 양호한 행이 더 있으면 더 많은 바이트 오프셋이 인쇄됩니다. 마지막 행이 사용됩니다.)

따라서 18바이트 이후에 오류가 발생했습니다. 에서 줄 번호를 얻는 것은 쉽습니다. head -c 18 new.csv | wc -l이는 2(양호한 줄 수)를 의미합니다. 따라서 오류는 라인 3에 있습니다. 실제로 r2c2 주변의 참조는 닫히지 않습니다.

관련 정보