I have a text file with tabs as separator:

a   1   956 9723
b   2   2   11432
c   3   1307    2964
c   4   2   12586
d   5   1377    11726
e   6   1735    8416
f   7   1320    10443
g   8   1175    9240
h   9   1598    9357
i   10  1405    2066

and I followed the example on nixCraft to extract the first column and last column:

while IFS="\t" read -r f1 f2 f3 f4
    echo "$f1"
    echo "$f4"
done < file.txt

It just returns the whole line. What went wrong?

System: CentOS 7, bash 4.2

  • 1
    Either use IFS=$'\t' or use a literal TAB in IFS. – user218374 Mar 25 '17 at 10:25
  • @RakeshSharma thanks! I tried IFS=$"\t" 'cause I saw some post on SO using dollar sign before the separator, but it didn't work. However, you suggestion worked! Could you please explain more about the single/doube quote here? – leoce Mar 25 '17 at 10:31
  • The $'..' is a carryover from ksh onto bash' n some other shells, most notably, zsh. What it does is express escape sequences, e.g., \n \t etc. With double quotes, it's not special and IFS gets set to two chars backslash n a t and since you did not have a t in your input you didn't observer it's after effects. Try with IFS=$"\t" and some lines with "t" sprinkled in them.... – user218374 Mar 25 '17 at 10:43
  • But to steer clear of shell anachronisms, use the method I ve detailed in the answer section below as it's completely shell agnostic (csh not included, ofc) – user218374 Mar 25 '17 at 10:47
TAB=`echo 'x' | tr 'x' '\011'`; # tab
while IFS="$TAB" read -r f1 f2 f3 f4 junk; do
   printf '$f1=<%s>\n' "$f1"
   printf '$f4=<%s>\n' "$f4"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.