Delimited data conversion
Convert Pipe-Delimited Text to CSV with a Parser
Convert Pipe-Delimited Text to CSV with a Parser. Preserve field values with explicit parsing, encoding and a checked output round trip.
Convert a pipe-delimited text file by telling a parser that the vertical bar separates fields, then writing comma-delimited records. A pipe can also occur inside a quoted value, so replacing every vertical bar with a comma does not reliably preserve the data.
Identify how the source escapes its values
The example supports the ordinary quote-aware dialect used by Python’s CSV reader with delimiter set to a vertical bar. If your source uses backslash escapes, has no quoting, or allows a different record terminator, describe that dialect explicitly. The word pipe-delimited alone does not define every escaping rule.
For a checked sample, use id|name|note as the header and a record whose note is quoted as A|B. A parser should recover the complete note A|B as one field. The resulting CSV still contains that vertical bar as data; conversion changes field separators, not every occurrence of the symbol.
Reject inconsistent record widths
The script verifies that each parsed record has the same number of fields as the header. An unquoted extra pipe can create an extra field and cause an explicit failure. Do not silently discard that field or shift later columns left merely to produce a file with the expected extension.
An empty field between two adjacent pipes is different from a missing field. The former is an empty string in the record, while the latter produces fewer fields than expected. Preserve the distinction during validation so an absent value is not silently mistaken for a shifted column.
Verify the comma-delimited output
The CSV writer handles embedded commas and quotation marks under its output dialect. Reopen the result with a comma-aware parser and compare the values. This verifies both the old separator’s interpretation and the new separator’s escaping behavior.
Keep the source file and write to a new destination name. If the receiver requires semicolons or a particular encoding instead of UTF-8 comma-separated records, change the writer under that explicit contract and repeat the same parser round trip. The .csv extension alone does not settle those choices.
Executable conversion example
import csv
with open("input.txt", encoding="utf-8-sig", newline="") as source:
rows = list(csv.reader(source, delimiter="|", strict=True))
if not rows or not rows[0]:
raise ValueError("Expected a header row")
if any(len(row) != len(rows[0]) for row in rows):
raise ValueError("Every record must have the same number of fields")
with open("output.csv", "w", encoding="utf-8", newline="") as target:
csv.writer(target, delimiter=",", lineterminator="\n").writerows(rows)
with open("output.csv", encoding="utf-8", newline="") as check:
assert list(csv.reader(check, delimiter=",", strict=True)) == rows
Use a representative acceptance fixture
Begin with two different data records containing a leading-zero identifier, an embedded comma, a quotation mark, an empty field and a non-ASCII name when the destination supports it. Read the output with a parser for the destination format and compare the actual values, column order and record count. A save message or familiar extension does not establish that the records survived correctly.
Change the second fixture’s values rather than rerunning only the same sample. Include a malformed record and confirm that the conversion reports it instead of producing a misleading success. Keep the original unchanged and write the result to a separate path. Avoid exposing sensitive source values in public error logs.
Choose the format-aware operation
The Convert Text to CSV tool here works with already extracted plain text. It does not infer every structured file format or replace the Python parsers shown above. Use the operation whose input contract matches the actual source, and verify the result independently before importing it into another application.
Python reference
Python’s CSV module documentation explains the parser and writer dialect options. The published snippets and acceptance cases in this family are executed locally against disposable fixtures.


