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

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to