98
votes

How do I select the first column from the TAB separated string?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

The above will return the entire line and not just "LOAD_SETTLED" as expected.

Update:

I need to change the third column in the tab separated values. The following does not work.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

This however works as expected if the separator is comma instead of tab.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt
6
awk 'BEGIN { FS = "[ \t]+" } ; { print $1 }' # this is what I was looking for. Is my google search correct? :) - shantanuo
Thanks to this comment, I have discovered: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txt to print tab-delimited values of the first three columns. - Wok
Or perhaps simply awk 'BEGIN {OFS="\t"}; {print $1,$2,$3}' - Josiah Yoder
Both GNU and BSD awk support -v for setting variables. It's ugly to use BEGIN {FS="\t"} inside an inline program, and any open source contribution you try to make like that is likely to be objected to. Only do that if you are writing a program file. Also, it is discouraged to use -F instead of -v FS= because the latter makes clear that only FS is being set and not OFS. Confusion about that last point is what caused this post in the first place. That's why "good style" is important. - Bruno Bronosky
Please, no one, ever, should do what @Wok demonstrated. You don't enumerate [Input] Field Separators in your Output. You specify an Output Field Separator via the OFS variable. - Bruno Bronosky

6 Answers

147
votes

You need to set the OFS variable (output field separator) to be a tab:

echo "$line" | 
awk -v var="$mycol_new" -F'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(make sure you quote the $line variable in the echo statement)

22
votes

Make sure they're really tabs! In bash, you can insert a tab using C-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED
18
votes

You can set the Field Separator:

... | awk 'BEGIN {FS="\t"}; {print $1}'

Excellent read:

https://docs.freebsd.org/info/gawk/gawk.info.Field_Separators.html

17
votes

Use:

awk -v FS='\t' -v OFS='\t' ...

Example from one of my scripts.

I use the FS and OFS variables to manipulate BIND zone files, which are tab delimited:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

This is a clean and easy to read way to do this.

5
votes
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'
-2
votes

Should this not work?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'