S3, Parquet & Excel
Read from S3
Use s3://bucket/key as an input file, in any input format, or with getline:
zawk -i csv '{ print $1 }' s3://bucket1/demo.csv
zawk -i parquet '{ print $FI["name"] }' s3://bucket1/demo.parquet
zawk 'BEGIN { while ((getline line < "s3://bucket1/demo.csv") > 0) print line }'
Settings are read from environment variables, also from .env in the current directory:
S3_ENDPOINT=http://127.0.0.1:9000
S3_ACCESS_KEY_ID=minioadmin
S3_ACCESS_KEY_SECRET=minioadmin
S3_REGION=us-east-1
The OPENDAL_S3_* and AWS_* names (AWS_ENDPOINT_URL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,
AWS_REGION) work too.
Objects are streamed: 8 MB parts are downloaded in parallel (4 at a time) while the program processes the data, so memory stays bounded for large objects. A missing bucket or object, or denied access, is reported before any input is processed.
Write results back with s3_put:
zawk -i csv -H '{ s[$FI["dept"]] += $FI["salary"] } END { s3_put("reports", "salary-by-dept.json", to_json(s)) }' \
s3://hr/employees.csv
Apache Parquet
zawk -i parquet '$FI["age"] > 30 { print $FI["name"], $FI["city"] }' family.parquet
zawk -i parquet -o csv '{ print $1, $2 }' family.parquet > family.csv
cat family.parquet | zawk -i parquet '{ print $0 }' # each row as a JSON object: JSON Lines
Values are converted as with -i jsonl:
- numbers and strings as is, decimals exactly, booleans as
1/0, null as"" DATE,TIME,TIMESTAMPas text:2024-01-15,13:45:30.5,2024-01-15 10:30:00(UTC)UUIDas text, other binary values as hexLIST,MAP,STRUCTandJSONcolumns as JSON text: process them withjson_value
Compressions: SNAPPY, ZSTD, LZ4 and uncompressed. With several files, columns are matched by name with those of the first file.
Write Parquet
The first printed record is the header; a column name may end with :TYPE:
zawk -i csv -H -o parquet --out-file users.parquet \
'NR == 1 { print "id:int64", "name", "age:int32", "created:timestamp" }
{ print $FI["id"], $FI["name"], $FI["age"], $FI["created_at"] }' users.csv
Convert JSON Lines to Parquet
zawk -i jsonl -o parquet --out-file events.parquet \
'NR == 1 { print "ts:timestamp", "level", "msg" } { print $FI["ts"], $FI["level"], $FI["msg"] }' events.jsonl
Excel
.xlsx files are read as CSV (from column A); -H makes the first row the header:
zawk -H '$FI["age"] > 40 { print $FI["name"] }' people.xlsx
zawk -i xlsx '{ print $1, $2 }' 'book.xlsx#Sheet2' # select a sheet (name matched ignoring case)
zawk inspect 'book.xlsx#Sheet2' # schema, sample rows, summary
Dates are 2024-01-05 or 2024-01-05 13:45:10, times 08:30:00, booleans 1/0, empty cells "".
.xls, .xlsm, .xlsb and .ods are read too.
# Excel -> Markdown table for a PR description
zawk -H -o md 'NR == 1 { print "name", "age" } { print $FI["name"], $FI["age"] }' people.xlsx
Compressed files
gzip, zstd, bzip2, xz and lz4 input is detected and decompressed automatically, locally, over HTTP and on S3:
zawk '$9 == 500' access.log.gz
zawk -i jsonl '{ print $FI["id"] }' s3://logs/2026/10/28/events.jsonl.zst