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