From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1PtnrO-0000ho-6B for garchives@archives.gentoo.org; Sun, 27 Feb 2011 21:08:58 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 395141C060; Sun, 27 Feb 2011 21:07:18 +0000 (UTC) Received: from mx.virtyou.com (mx.virtyou.com [94.23.166.77]) by pigeon.gentoo.org (Postfix) with ESMTP id ED3C81C060 for ; Sun, 27 Feb 2011 21:07:17 +0000 (UTC) Received: from [192.168.2.43] (p5791010B.dip.t-dialin.net [87.145.1.11]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mx.virtyou.com (Postfix) with ESMTPSA id CDD9B496AE5 for ; Sun, 27 Feb 2011 22:07:16 +0100 (CET) Message-ID: <4D6ABCC2.3050109@wonkology.org> Date: Sun, 27 Feb 2011 22:06:10 +0100 From: Alex Schuster User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-user@lists.gentoo.org Reply-to: gentoo-user@lists.gentoo.org MIME-Version: 1.0 To: gentoo-user@lists.gentoo.org Subject: Re: [gentoo-user] OT: cut replacement with bash builtins References: <4D6AADAA.60807@binarywings.net> In-Reply-To: <4D6AADAA.60807@binarywings.net> Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit X-Archives-Salt: X-Archives-Hash: a1f398dff99b241de6131766027349aa 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? > 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. 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