30

I'm taking the following structure from around the net as a basic example of how to read from a file in BASH:

cat inputfile.txt | while read line; do echo $line; done

My inputfile.txt is tab-delimited, though, and the lines that come out of the above command are space-delimited.

This is causing me problems in my actual application, which is of course more complex than the above: I want to take the line, generate some new stuff based on it, and then output the original line plus the new stuff as extra fields. And the pipeline is going to be complicated enough without a bunch of cut -d ' ' and sed -e 's/ /\t/g' (which wouldn't be safe for tab-delimited data containing spaces anyway).

I've looked at IFS solutions, but they don't seem to help in this case. What I want is an OFS...except that I'm in echo, not awk! I think that if I could just get echo to spit out what I gave it, verbatim, I'd be in good shape. Any thoughts? Thanks!

Jenn D.
  • 1,045
  • 4
  • 13
  • 22
  • 2
    You often don't need to use cat as part of a pipeline, just redirect stdin of the next command directly from the file: `while read line; do echo $line; done < inputfile.txt` – Adrian Pronk Feb 27 '11 at 05:57

1 Answers1

38

Try:

cat inputfile.txt | while read line; do echo "$line"; done

instead.

In other words, it's not read replacing the tabs, it's echo.

See the following transcript (using <<tab>> where the tabs are):

pax$ echo 'hello<<tab>>there' | while read line ; do echo $line ; done
hello there

pax$ echo 'hello<<tab>>there' | while read line ; do echo "$line" ; done
hello<<tab>>there
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 2
    Good grief; it was that easy? Thanks! Good practice to put the quotes in anyway. – Jenn D. Feb 26 '11 at 16:07
  • 2
    Replacing the tabs is a conspiracy between (ba)sh and echo. `echo $line` splits line up into words, which are then globbed and passed separately to echo, which then joins them with spaces. `echo "$line"` passes the string as-is. By comparison, DOS/Windows `echo %line%` does neither of these things (and indeed even echos quote characters literally). – Neil Feb 26 '11 at 17:03
  • 13
    BTW `read` will strip leading and trailing whitespace, so if you want to preserve leading/trailing tabs, use `... while IFS= read line ...` (note that since the assignment to IFS is a prefix on the read command, it only applies to that and does not have to be reset afterward). – Gordon Davisson Feb 26 '11 at 17:23
  • 1
    Thanks Gordon,Your comment helps me a lot. – wukong Jul 10 '13 at 17:10