Loop through tab delineated file in bash script

The problem is in the command echo $line. Since there are no quotes around $line, the shell performs word splitting on it, then interprets each word as a globbing pattern. Try it out with

a='*.txt foo'
ls $a

In your case, the tabs separate words, which then become separate arguments to echo. The echo command prints its arguments separated by a space. So cut ends up receiving space-delimited fields instead of tab-delimited fields.

Always put double quotes around variable substitutions $foo and command substitutions $(foo) (unless you understand why you need to leave them out and why it's ok to do so). echo "$line" would work here, but it's a complicated way of doing what you propose.

Keeping your approach of parsing in the shell, you can make the read command parse the input into fields.

while read DB USER PASS; do
  echo "DB=$DB USER=$USER PASS=$PASS"
done <users.txt

read splits fields separated by characters in the value of the IFS variable, which consists of a space and a tab (plus a newline, which can't occur inside a line) by default. To split only at tabs, set IFS to a single tab first. Note that leading and trailing tabs are ignored and consecutive tabs count as a single one.

read treats \ as a special character: a backslash followed by a newline are ignored; \\ becomes a single backslash. If you want to avoid this behavior, pass the -r option.


How about this?

$ awk '{print "DB="$1"\tUSER="$2"\tPASS="$3}' users.txt
DB=drupal_1 USER=drupal1    PASS=tmmjXSWL
DB=drupal_2 USER=drupal2    PASS=FHiJSYHM
DB=drupal_3 USER=drupal3    PASS=b7bFNj06
DB=drupal_4 USER=drupal4    PASS=0AaV62EL

I can't tell if you have a problem to solve, or are wondering about a more theoretical issue.

Tags:

Bash