The classical approach is:
RESULT="$(echo "$LINE"| awk '{print $1}')" # executes in a subshell
Processing thousands of lines this way however fork()’s thousands of processes, which affects performance and makes your script CPU hungry.
Here is a more efficient way to do it:
LINE="col0 col1 col2 col3 col4 " COLS=() for val in $LINE ; do COLS+=("$val") done echo "${COLS[0]}"; # prints "col0" echo "${COLS[1]}"; # prints "col1" echo "${COLS[2]}"; # prints "col2" echo "${COLS[3]}"; # prints "col3" echo "${COLS[4]}"; # prints "col4"
If you want to split not by white-space but by any other character, you can temporarily change the IFS variable which determines how Bash recognizes fields and word boundaries.
P.S. For the record, here is the old solution:
# # OLD CODE # Update: Aug/2016: I've encountered a bug in Bash where this splitting doesn't work as expected! Please see the comments below. # # Here is the effective solution which I found with my colleagues at work: COLS=( $LINE ); # parses columns without executing a subshell RESULT="${COLS[0]}"; # returns first column (0-based indexes) # Here is an example: LINE="col0 col1 col2 col3 col4 " # white-space including tab chars COLS=( $LINE ); # parses columns without executing a subshell echo "${COLS[0]}"; # prints "col0" echo "${COLS[1]}"; # prints "col1" echo "${COLS[2]}"; # prints "col2" echo "${COLS[3]}"; # prints "col3" echo "${COLS[4]}"; # prints "col4"
February 20, 2013 at 1:23 pm
Nice 🙂 You should add a little bit of context to make it more obvious (wrap it in a loop).
February 21, 2013 at 2:38 pm
Done, thanks for the comment.
August 17, 2016 at 12:05 pm
Unfortunately, a bug was introduced between Bash versions 4.3.11 and 4.3.30. Here is a sample Bash script:
Here is the correct result when executed under Bash version 4.3.11:
Here is the incorrect result when executed under Bash version 4.3.30:
You can spot the difference for indexes “1” and “2”.
October 20, 2016 at 11:25 am
I’ve changed the proposed solution using a different approach. Hopefully it doesn’t hit any other Bash bugs.