Text and CSV conversion
Change Fixed-Width Text to CSV with Explicit Column Boundaries
Convert fixed-width text using documented field positions, validate record widths, and preserve identifiers instead of guessing where spaces divide columns.
A fixed-width text file can be converted to CSV by slicing each record at its documented column boundaries, then passing those fields to a CSV writer. Do not replace every run of spaces with a comma: a name can contain meaningful spaces, while padding can fill an otherwise empty field.
Obtain the field layout first
For the worked example, each source record contains exactly 22 characters. The identifier occupies the first five, the name the next twelve, and the code the final five. The source has no header. Padding consists of ordinary spaces at either end of each field and is intentionally removed.
| Field | Human column positions | Python slice |
|---|---|---|
| id | 1–5 | 0:5 |
| name | 6–17 | 5:17 |
| code | 18–22 | 17:22 |
These positions are an example, not a universal text-file format. Use the exporting system’s actual layout. If the source includes a header, trailer, page number or separator line, account for those record types explicitly instead of treating every line as a data record.
Slice complete records
import csv
rows = [["id", "name", "code"]]
with open("input.txt", encoding="utf-8-sig", newline="") as source:
for number, line in enumerate(source, 1):
record = line.rstrip("\r\n")
if len(record) != 22:
raise ValueError(f"Line {number}: expected 22 characters")
rows.append([
record[0:5].strip(" "),
record[5:17].strip(" "),
record[17:22].strip(" "),
])
with open("output.csv", "w", encoding="utf-8", newline="") as target:
csv.writer(target, lineterminator="\n").writerows(rows)
The source remains unchanged. The output starts with a CSV header that the script supplies. A value such as 00123 remains text, and a name such as Ana Li stays one field because the program never splits the name on its internal space.
Distinguish padding from data
Calling strip(" ") removes only ordinary space padding at field edges. That is correct only because the source contract says those edge spaces are padding. If leading or trailing spaces are meaningful data, preserve them and let the CSV writer quote them when necessary.
An all-space field becomes an empty string. Decide whether that represents an absent value, a deliberately blank value or an invalid record in your application. The conversion preserves the empty field’s position; it does not assign a business meaning to it.
Check what the column positions measure
Python string slicing counts Unicode code points after decoding. Some legacy export layouts specify byte offsets, and a visual report may use display columns. Those units can disagree for non-ASCII text, combining marks or wide characters. Do not apply this script unchanged to a byte-based specification.
Use a source encoding that matches the actual export. The example accepts UTF-8 with an optional byte-order mark. Replacing undecodable bytes with a replacement symbol would hide an input problem and can shift the intended field boundaries, so the script lets decoding errors stop the conversion.
Treat width errors as evidence
A line shorter or longer than 22 characters is rejected with its line number. Inspect that record and the export specification. It may be a damaged record, a different record type, or evidence that the proposed layout is wrong. Automatically padding or truncating it could create a plausible but incorrect table.
The destination is opened after every source line passes the width check. A failed validation therefore leaves an existing output.csv untouched. An empty source produces a header-only CSV; decide whether your receiving workflow permits zero data records.
Review the converted table
Parse the output as CSV and verify three fields per row. Test an identifier with leading zeros, a name containing a space, a field containing a comma and a blank padded field. Confirm that each remains in the expected column.
Keep the fixed-width original and its layout alongside the conversion instructions. CSV does not retain the original padding widths, so it cannot reconstruct the exact source bytes without that additional information.
Reference
Python’s CSV module handles quoting after the fixed-width fields have been extracted. It does not infer those field boundaries.


