Introduction
awk is a powerful command for efficient text processing, but one of the points where beginners tend to stumble is "handling of delimiters."
In particular, the concept of ofs is related not only to splitting input but also to output formatting, and there are many cases where people use it without a clear understanding.
This article carefully explains how awk handles columns and when ofs takes effect, and summarizes advanced techniques that can be used in practical work.
Reference: GNU awk
How awk Splits Columns
Creating the File
cat << 'EOF' > input.txt
apple orange banana
dog cat mouse
EOF
Command
awk '{print $1, $2, $3}' input.txt
Output
apple orange banana
dog cat mouse
Command
awk 'BEGIN{OFS=","} {print $1, $2, $3}' input.txt
Output
apple,orange,banana
dog,cat,mouse
How It Works
| Item | Description |
|---|---|
| FS | Input field separator (default is whitespace) |
| OFS | Output field separator (default is whitespace) |
| $1, $2... | Retrieve data on a per-field basis |
| Outputs with OFS inserted between fields |
Explanation
awk splits input using FS and joins output using OFS.
By changing OFS, you can freely control the delimiter.
Default OFS and the Behavior of “Single Space”
Creating the File
cat << 'EOF' > input.txt
A B C
1 2 3
EOF
Command
awk '{print $1, $2, $3}' input.txt
Output
A B C
1 2 3
Command
awk 'BEGIN{OFS=" "} {print $1, $2, $3}' input.txt
Output
A B C
1 2 3
Command
awk 'BEGIN{OFS=","} {print $1, $2, $3}' input.txt
Output
A,B,C
1,2,3
How It Works
| Item | Description |
|---|---|
| OFS | Output Field Separator |
| Default value | Single space " " |
| Behavior of print $1, $2 | OFS is automatically inserted between fields |
| OFS=" " | Same as default (explicitly specified) |
| OFS="," | Output is comma-separated |
Explanation
By default, awk uses a "single space" for OFS, so the output is space-delimited even without specifying anything. By changing OFS, you can flexibly control the output format.
Conditions Under Which OFS Takes Effect
Creating the File
cat << 'EOF' > input.txt
a b c
1 2 3
EOF
Command
awk '{print $1, $2, $3}' input.txt
Output
a b c
1 2 3
Command
awk 'BEGIN{OFS=","} {print $1, $2, $3}' input.txt
Output
a,b,c
1,2,3
Command
awk '{print $1 "-" $2 "-" $3}' input.txt
Output
a-b-c
1-2-3
How It Works
| Condition | OFS Effect | Description |
|---|---|---|
| print $1, $2 with comma separation | Affected | OFS is used as the separator between fields |
| BEGIN{OFS=","} specified | Enabled | Changes the delimiter character at output time |
| String concatenation like $1 "-" $2 | Not affected | Concatenation is treated as a single string, so OFS is not used |
Explanation
OFS is applied only "when multiple fields are output with comma separation in print."
In the case of string concatenation, the result becomes a single value, so OFS is not involved.
How to Specify Major Delimiter Characters
Creating the File
cat << 'EOF' > input.txt
apple orange banana
cat dog mouse
red blue green
EOF
Command
awk '{print $1, $2, $3}' input.txt
Output
apple orange banana
cat dog mouse
red blue green
Command
awk 'BEGIN{OFS=","} {print $1, $2, $3}' input.txt
Output
apple,orange,banana
cat,dog,mouse
red,blue,green
How It Works
| Item | Description |
|---|---|
| OFS | Output Field Separator |
| Default | Space |
| How to set | BEGIN{OFS="delimiter"} |
| Scope of effect | Applied between items comma-separated in print |
| Note | Not applied when fields are listed without commas like $1 $2 |
Explanation
OFS is a variable for changing the output delimiter when fields are comma-separated in print. It is commonly used when converting to CSV format and similar formats.
Setting Multibyte Characters or Symbols as Delimiters
Creating the File
cat << 'EOF' > input.txt
apple banana cherry
dog elephant fox
EOF
Command
awk 'BEGIN{OFS="★"} {print $1,$2,$3}' input.txt
Output
apple★banana★cherry
dog★elephant★fox
Command
awk 'BEGIN{OFS="あいう"} {print $1,$2,$3}' input.txt
Output
appleあいうbananaあいうcherry
dogあいうelephantあいうfox
How It Works
| Element | Description |
|---|---|
| OFS | Output Field Separator |
| BEGIN | A block executed only once before input processing |
| $1,$2,$3 | Each field (space-separated) |
| Joins fields with OFS and outputs | |
| Multibyte characters | Japanese and symbols can also be set in OFS |
Explanation
OFS specifies the delimiter at output time, and multibyte characters such as Japanese and symbols can be used without issue. This enables flexible formatted output.
Technique for Rebuilding $0 to Forcibly Apply OFS
Creating the File
cat << 'EOF' > input.txt
apple orange banana
dog cat mouse
EOF
Command
awk 'BEGIN{OFS=","} {$1=$1; print}' input.txt
Output
apple,orange,banana
dog,cat,mouse
How It Works
| Element | Description |
|---|---|
| OFS | Output Field Separator |
| $1=$1 | Trigger that reassigns a field to force $0 to be rebuilt |
| $0 | The entire line (OFS is applied when rebuilt) |
| Outputs the rebuilt $0 |
Explanation
By using $1=$1, awk rebuilds the line, and OFS is forcibly applied at that point.
This allows the output format to be unified regardless of the input delimiter.
Output Control Through NF (Number of Fields) Manipulation and Its Relationship with OFS
Creating the File
cat << 'EOF' > input.txt
apple orange banana
cat dog
red blue green yellow
EOF
Command
awk '{print $1, $2}' input.txt
Output
apple orange
cat dog
red blue
Command
awk 'BEGIN{OFS=","} {print $1, $2}' input.txt
Output
apple,orange
cat,dog
red,blue
Command
awk '{NF=1; print $0}' input.txt
Output
apple
cat
red
Command
awk 'BEGIN{OFS="-"} {NF=2; print $0}' input.txt
Output
apple-orange
cat-dog
red-blue
How It Works
| Element | Description | Behavior |
|---|---|---|
| NF | Number of fields (columns) | Changing the value changes the number of fields included in output |
| $1, $2 | Each field | Outputs only the specified columns |
| OFS | Output field separator | Controls the delimiter character at print time |
| NF=1 | Field reduction | Keeps only column 1 and removes the rest |
| NF=2 | Field adjustment | Limits to 2 columns and rebuilds |
| print $0 | Entire line | The content after NF change is reconstructed and output |
Explanation
When NF is rewritten, awk reconstructs the record, and OFS is used as the delimiter at that point.
In other words, NF manipulation and OFS work together to determine the output format.
Flexible Line Break Control Combined with ORS (Output Record Separator)
Creating the File
cat << 'EOF' > input.txt
apple orange banana
cat dog elephant
red blue green
EOF
Command
awk 'BEGIN{ORS=" | "} {for(i=1;i<=NF;i++) print $i}' input.txt
Output
apple | orange | banana | cat | dog | elephant | red | blue | green |
Command
awk 'BEGIN{OFS=", "; ORS="\n---\n"} {$1=$1; print}' input.txt
Output
apple, orange, banana
---
cat, dog, elephant
---
red, blue, green
---
How It Works
| Element | Role | Description |
|---|---|---|
| ORS | Output Record Separator | Changes the delimiter per print, controlling line breaks and arbitrary strings |
| OFS | Output Field Separator | Specifies the delimiter character between fields |
| NF | Number of fields | Used to handle all fields in loop processing |
| $1=$1 | Rebuild trigger | Re-outputs the entire line reflecting OFS |
Explanation
Using ORS allows flexible control of the output format including line breaks, and combining it with OFS greatly increases formatting freedom.
It works especially powerfully for log formatting and one-liner processing.
Fixed Format and Dynamic Delimiters
Creating the File
cat << 'EOF' > input.txt
apple 100 red
banana 200 yellow
grape 300 purple
EOF
Command
awk 'BEGIN{OFS=","} {print $1, $2, $3}' input.txt
Output
apple,100,red
banana,200,yellow
grape,300,purple
Command
awk 'BEGIN{OFS=" | "} {OFS="-"; print $1, $2, $3}' input.txt
Output
apple-100-red
banana-200-yellow
grape-300-purple
How It Works
| Element | Description |
|---|---|
| awk | Text processing tool |
| BEGIN{} | Executed only once before processing begins |
| OFS | Output Field Separator |
| $1,$2,$3 | Specifies each column (field) |
| Outputs the specified fields | |
| Dynamic delimiter | Output format can be flexibly changed by modifying OFS |
Explanation
By setting OFS, you can freely change the delimiter character at output time.
This makes it easy to generate different formats from the same data.
Field Joining by Setting an Empty String
Creating the File
cat << 'EOF' > input.txt
A 1
B 2
C 3
EOF
Command
awk 'BEGIN{OFS=""} {print $1, $2}' input.txt
Output
A1
B2
C3
How It Works
| Element | Description |
|---|---|
| OFS | Output Field Separator |
| OFS="" | Sets the delimiter to empty |
| print $1, $2 | Fields are originally joined by OFS between them |
| Result | The delimiter disappears and fields are concatenated |
Explanation
By setting OFS to an empty string, the delimiter between fields disappears and they are concatenated. This is a fundamental technique for output control in awk.
CSV Format Data Conversion Flow
Creating the File
cat << 'EOF' > input.txt
name age city
Alice 25 Tokyo
Bob 30 Osaka
EOF
Command
awk 'BEGIN {OFS=","} {print $1, $2, $3}' input.txt
Output
name,age,city
Alice,25,Tokyo
Bob,30,Osaka
Command
awk 'BEGIN {OFS=","} NR>1 {print $1, $2, $3}' input.txt
Output
Alice,25,Tokyo
Bob,30,Osaka
How It Works
| Item | Description |
|---|---|
| awk | Text processing tool |
| OFS | Output Field Separator |
| BEGIN | Executed only once before processing |
| NR | Line number (Number of Records) |
| Joins fields with OFS and outputs |
Explanation
By using awk's OFS, you can easily convert space-delimited data to CSV.
The key point is to specify OFS in BEGIN.
Practical Summary for Mastering awk’s OFS
By correctly understanding the relationship between awk and ofs, you can use it as an advanced data formatting tool, going one step beyond a simple text processing tool.
You may be confused by the differences in behavior at first, but by grasping the key points introduced in this article, you will be able to consistently obtain the intended output.
