A B
C D
E F
Suppose you want to do something for each line in file. The most obvious way is to use a for loop - it almost matches how you think about it! So lets try (input line followed by output):
(/tmp ): for line in $(cat input.txt); do echo $line; done; A B C D E FNot quite ideal; for uses the Bash IFS variable (ref) to detect token boundaries. IFS defaults to any whitespace (eg space, tab, line-break) so we get each token rather than each line. Handy in some circumstances but here we specifically want each line.
We can set and unset IFS (unset will return it to default; if we were really feeling careful we could store and restore the value in case someone else set it already):
(/tmp ): IFS='\n'; for line in $(cat input.txt); do echo $line; done; unset IFS; A B C D E F (/tmp ): for line in $(cat input.txt); do echo $line; done; A B C D E FNote that the first for sets & unsets IFS; this ensure the second for (which doesn't set IFS) still behaves as expected. That's ugly damnit! More important, we failed we could leave IFS set and disrupt every future script run in this terminal.
We can use the builtin read command (ref) instead and construct our for-each line using while read:
(/tmp ): while read -r line; do echo $line; done < input.txt; A B C D E FSplendiferous! We get each line and we don't have to futz about with IFS. The -r argument to read disables backslash escaping to se read the literal content of the line without any special mangling.
5 comments:
This is an interesting tip :)
Javin
most useful cvs commands in linux/unix
Exactly what I was looking for.
now to figure out how to do this with tcsh...
Change: IFS='\n'
for: IFS=$'\n'
Great article! The one-liners for the Bash for-each loop are super handy and make scripting much more efficient. I especially love the practical examples you provided. Thanks for sharing these tips!"
Digital Marketing Course In Hyderabad
Post a Comment