extract a line from multi-line variable

extract a line from multi-line variable

Post by Pavel Soroki » Tue, 30 Oct 2001 13:53:45



Hello,

I have a variable which stores several lines of text (e.g. output from
ls). How can I extract the first (or any) line from it to another
variable? "for f in $files" doesn't work for me, as I need only the
first line.

Another question: I have to parse many files in many directories,
extracting data from them, etc. I feel that bash script is not powerful
enouth for such a task. Is Perl a better tool for it?

Thanks!
Pavel

 
 
 

extract a line from multi-line variable

Post by Chris F.A. Johnso » Tue, 30 Oct 2001 14:33:20



> I have a variable which stores several lines of text (e.g. output from
> ls). How can I extract the first (or any) line from it to another
> variable? "for f in $files" doesn't work for me, as I need only the
> first line.

LINE=3
echo "$files" | awk "NR == $LINE"

Quote:> Another question: I have to parse many files in many directories,
> extracting data from them, etc. I feel that bash script is not powerful
> enouth for such a task. Is Perl a better tool for it?

I've found very little I can't do with a bash script (including a liberal
use of awk).

I've tried perl on occasion, but, each time, I realized I could do what I
needed just as easily with a shell script.

--
    Chris F.A. Johnson                        http://cfaj.freeshell.org
    ===================================================================
    My code (if any) in this post is copyright 2001, Chris F.A. Johnson
    and may be copied under the terms of the GNU General Public License

 
 
 

extract a line from multi-line variable

Post by t.. » Tue, 30 Oct 2001 20:22:38



> I have a variable which stores several lines of text (e.g. output from
> ls). How can I extract the first (or any) line from it to another
> variable? "for f in $files" doesn't work for me, as I need only the
> first line.

With ksh, bash or the like you can get the first line easily:

LINE1="${VAR%%
*}"

and the last line like this:

LASTLINE="${VAR##*

Quote:}"

Intermediate lines are harder to get that, but not impossible.
E.g.,

TMP="${VAR#*

Quote:}"

LINE2="${TMP%%
*}"
TMP="${TMP#*
Quote:}"

LINE2="${TMP%%
*}"

etc.

With ksh you can also turn the variable into an array:

OLDIFS="$IFS"
IFS="
"
set -A array "$VAR"
IFS="$OLDIFS"

and access them with "${array[0]}" &c.

If you don't care about efficiency or if you need to
do it with Bourne sh, you can try this:

LINE1=`echo "$VAR" | sed -n 1p`

substituting whichever line you want for '1'.
Beware of special characters in that though, echo
is likely to mess them up.

Quote:> Another question: I have to parse many files in many directories,
> extracting data from them, etc. I feel that bash script is not powerful
> enouth for such a task. Is Perl a better tool for it?

Bash is powerful for such things, although perl is probably faster.
I'd suggest using whichever you know better (or want to learn).

--
Tapani Tarvainen

 
 
 

extract a line from multi-line variable

Post by Stephane CHAZEL » Wed, 31 Oct 2001 04:15:03



[...]

Quote:> With ksh you can also turn the variable into an array:

> OLDIFS="$IFS"
> IFS="
> "
> set -A array "$VAR"
> IFS="$OLDIFS"

> and access them with "${array[0]}" &c.

But beware that for example if
VAR="
line 2

line 4"

Your array will contain only two fields: "line 2" and "line 4" although
VAR contains 4 lines.

With zsh, you can work around this with
IFS=$'\n\n'
Once repeated twice, an IFS white space character is no more considered
special.

With zsh, you can also do:

line3=${${(f)VAR}[3]}

Quote:

> If you don't care about efficiency or if you need to
> do it with Bourne sh, you can try this:

Note that Bourne sh also has arrays (the positional parameters)

IFS="
"
set -- $VAR
line3=$3

Quote:

> LINE1=`echo "$VAR" | sed -n 1p`

> substituting whichever line you want for '1'.
> Beware of special characters in that though, echo
> is likely to mess them up.

Maybe instead:

line_number=3
LINE=`sed -e $line_number'!d' -e q` << EOF
$VAR
EOF

--
Stphane