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

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

약 1000행의 CSV 파일이 있는데 이를 가져오려는 위치에서 700행에 오류가 발생합니다. 그러나 이 CSV의 항목에는 개행 문자가 포함되어 있고 인용되어 있으므로 매우 빠르게 사용할 수 없습니다. awk또는 행 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행)을 stdout으로 간단히 덤프하려면 어떻게 해야 합니까?


편집: 발견됨(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 -l2(좋은 줄 수)입니다. 따라서 오류는 3행에 있습니다. 실제로 그렇습니다. r2c2 주변의 인용문은 닫히지 않았습니다.

관련 정보