Am 27.02.2011 22:06, schrieb Alex Schuster: > Florian Philipp writes: > >> I'm currently streamlining some of my shell scripts to avoid unnecessary >> process calls where bash itself is powerful enough. >> >> At the moment, I want to replace stuff like this: >> string='foo:bar:foo' >> second_field=$(echo $string | cut -d : -f 2) # should read "bar" >> >> My current solution is using two string operations: >> string='foo:bar:foo' >> # remove everything up to and including first ':' >> second_and_following=${string#*:} >> # remove everything from the first ':' following >> second_field=${second_and_following%%:*} > > That's how I do these things, too. > >> Of course, I normally do this in a single line with a subshell but it > > Hmm, I don't get this. Subshell? second_field=$(second_and_following=${string#*:}; echo ${second_and_following%%:*}) Putting it in parentheses creates a subshell. New variables don't leave the scope. I guess I should have said command substitution but both concepts apply here. > >> still looks cumbersome. Is there a way to do it in a single operation >> without a temporary variable? The following does not work: >> string='foo:bar:foo' >> second_field=${string#:%%:*} > > I don't think so. But you can write a shell function for this: > > getfield() > { > local str=${1#*:} > echo "${str%%:*} > } > > string='foo:bar:foo' > second_field=$( getfield "$string" ) > > But if you need to do this very often in a loop, sometimes going back to > cut can speed things up, when you place it outside: > > See > > for string in $( < inputfile ) > do > second_field=$( getfield "$string" ) > do_something_with $second_field > done > > vs. > > secondfields=( $( cut -d : -f 2 inputfile ) ) > for secondfield in ${secondfields[@]} > do > do_something_with $second_field > done > > So, in th e2nd example, cut is called only once, but processes all input > lines. The result is put into an array. > Agreed. Using one long pipe (when applicable) is the real strength of shell programming. > Of course, all stuff should be put into double quotes in case there is > whitescape involved. Setting IFS to $'\n' may be necessary for this when > creating the array. > > Wonko > Agreed, again. I removed the quotes from my examples to improve readability. It was already bad enough with all those regular expressions. Thanks for the input. Florian Philipp