mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-17 16:38:54 +00:00
Say so in the error message when a CSV/TSV length-mismatch line is blank (#1572)
Trailing blank lines at the end of a CSV/TSV file produce a header/data length mismatch error which, especially for large files, gives no clue that the offending line is simply blank. Since #2146 (issue #1535), the skip-trivial-records verb is an opt-in way to have such lines skipped -- but users hitting the error had no pointer to it. Now, when the mismatching input line is blank, the CSV and TSV readers append a hint to the error message: mlr: CSV header/data length mismatch 2 != 1 at filename tmp.csv row 4; this input line is blank -- use the skip-trivial-records verb to have blank input lines skipped Errors for genuinely ragged, non-blank lines are unchanged, as is all non-error behavior. Also adds a note to the CSV/JSON troubleshooting docs page about trailing blank lines and skip-trivial-records. Addresses #1572. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
a63ea57359
commit
b515e6f18a
13 changed files with 35 additions and 6 deletions
|
|
@ -27,6 +27,10 @@ When Miller reports a parse error, it is often useful to first identify whether
|
|||
`--csvlite` or `--icsvlite` instead. See also [File Formats](file-formats.md).
|
||||
- If a CSV error mentions a "header/data length mismatch", inspect the reported input line for an
|
||||
unquoted comma, a missing closing quote, or an unexpected extra delimiter.
|
||||
- A common cause of header/data length mismatches is one or more blank lines at the end of the
|
||||
file -- in that case the error message says the input line is blank. Use the
|
||||
`skip-trivial-records` verb to have blank input lines skipped, e.g. `mlr --csv
|
||||
skip-trivial-records then cat file.csv`.
|
||||
- For CSV generated by spreadsheets or hand-written scripts, `--csv-trim-leading-space` can help
|
||||
when fields look like `"foo", "bar"`, where the second field has a leading space before the quote.
|
||||
- For non-standard CSV that contains stray quote characters, `--lazy-quotes` can help Miller accept
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ When Miller reports a parse error, it is often useful to first identify whether
|
|||
`--csvlite` or `--icsvlite` instead. See also [File Formats](file-formats.md).
|
||||
- If a CSV error mentions a "header/data length mismatch", inspect the reported input line for an
|
||||
unquoted comma, a missing closing quote, or an unexpected extra delimiter.
|
||||
- A common cause of header/data length mismatches is one or more blank lines at the end of the
|
||||
file -- in that case the error message says the input line is blank. Use the
|
||||
`skip-trivial-records` verb to have blank input lines skipped, e.g. `mlr --csv
|
||||
skip-trivial-records then cat file.csv`.
|
||||
- For CSV generated by spreadsheets or hand-written scripts, `--csv-trim-leading-space` can help
|
||||
when fields look like `"foo", "bar"`, where the second field has a leading space before the quote.
|
||||
- For non-standard CSV that contains stray quote characters, `--lazy-quotes` can help Miller accept
|
||||
|
|
|
|||
|
|
@ -34,3 +34,15 @@ func hasNonEmptyField(fields []string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// blankInputLineHint returns a hint to be appended to CSV/TSV header/data
|
||||
// length mismatch errors when the offending input line is blank -- e.g. one
|
||||
// or more blank lines at the end of the file. Without this, the bare
|
||||
// mismatch error can be hard to act on, especially for large files. See
|
||||
// issue #1572.
|
||||
func blankInputLineHint(fields []string) string {
|
||||
if hasNonEmptyField(fields) {
|
||||
return ""
|
||||
}
|
||||
return "; this input line is blank -- use the skip-trivial-records verb to have blank input lines skipped"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,8 +269,8 @@ func (reader *RecordReaderCSV) getRecordBatch(
|
|||
continue
|
||||
}
|
||||
err := fmt.Errorf(
|
||||
"CSV header/data length mismatch %d != %d at filename %s row %d",
|
||||
nh, nd, reader.filename, reader.rowNumber,
|
||||
"CSV header/data length mismatch %d != %d at filename %s row %d%s",
|
||||
nh, nd, reader.filename, reader.rowNumber, blankInputLineHint(csvRecord),
|
||||
)
|
||||
errorChannel <- err
|
||||
return
|
||||
|
|
|
|||
|
|
@ -193,8 +193,9 @@ func getRecordBatchExplicitTSVHeader(
|
|||
continue
|
||||
}
|
||||
err := fmt.Errorf(
|
||||
"TSV header/data length mismatch %d != %d at filename %s line %d",
|
||||
"TSV header/data length mismatch %d != %d at filename %s line %d%s",
|
||||
len(reader.headerStrings), len(fields), filename, reader.inputLineNumber,
|
||||
blankInputLineHint(fields),
|
||||
)
|
||||
errorChannel <- err
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
mlr: CSV header/data length mismatch 2 != 1 at filename test/input/pr-1346.csv row 4
|
||||
mlr: CSV header/data length mismatch 2 != 1 at filename test/input/pr-1346.csv row 4; this input line is blank -- use the skip-trivial-records verb to have blank input lines skipped
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
mlr: TSV header/data length mismatch 1 != 0 at filename test/cases/io-spec-tsv/0004/single-column-with-blank.tsv line 4
|
||||
mlr: TSV header/data length mismatch 1 != 0 at filename test/cases/io-spec-tsv/0004/single-column-with-blank.tsv line 4; this input line is blank -- use the skip-trivial-records verb to have blank input lines skipped
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
mlr: CSV header/data length mismatch 2 != 1 at filename test/cases/verb-skip-trivial-records/0005/input.csv row 3
|
||||
mlr: CSV header/data length mismatch 2 != 1 at filename test/cases/verb-skip-trivial-records/0005/input.csv row 3; this input line is blank -- use the skip-trivial-records verb to have blank input lines skipped
|
||||
|
|
|
|||
1
test/cases/verb-skip-trivial-records/0009/cmd
Normal file
1
test/cases/verb-skip-trivial-records/0009/cmd
Normal file
|
|
@ -0,0 +1 @@
|
|||
mlr --itsv --otsv cat ${CASEDIR}/input.tsv
|
||||
1
test/cases/verb-skip-trivial-records/0009/experr
Normal file
1
test/cases/verb-skip-trivial-records/0009/experr
Normal file
|
|
@ -0,0 +1 @@
|
|||
mlr: TSV header/data length mismatch 2 != 0 at filename test/cases/verb-skip-trivial-records/0009/input.tsv line 3; this input line is blank -- use the skip-trivial-records verb to have blank input lines skipped
|
||||
2
test/cases/verb-skip-trivial-records/0009/expout
Normal file
2
test/cases/verb-skip-trivial-records/0009/expout
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
a b
|
||||
1 2
|
||||
4
test/cases/verb-skip-trivial-records/0009/input.tsv
Normal file
4
test/cases/verb-skip-trivial-records/0009/input.tsv
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
a b
|
||||
1 2
|
||||
|
||||
|
||||
|
0
test/cases/verb-skip-trivial-records/0009/should-fail
Normal file
0
test/cases/verb-skip-trivial-records/0009/should-fail
Normal file
Loading…
Add table
Add a link
Reference in a new issue