Daniel R
Daniel R

Reputation: 17

Assign lines to variables with separator in bash

I have a file built from a grep output and it looks like this :

http://google.fr
Pierre google
http://test.fr
--
http://yahoo.com
Jean Yahoo
http://test.fr
--

I made a separator '--' for every 3 lines. I would like to assign every line to a variable, for example :

url= "http://google.fr"
name= "Pierre Google"
web= "http://test.fr"

So I made the bash script with IFS=-- and I have tried with the -d option for echo but i don't know how I could assign these 3 lines to a variable for every block.

Thanks for your help

Upvotes: 1

Views: 1025

Answers (3)

dawg
dawg

Reputation: 104111

You can preprocess the file into a more typical format to use IFS to separate into fields (or variables) with a utility such as awk or sed:

while IFS="|" read -r url name web; do
    echo "$url" "$name" "$web"
done  < <(awk 'BEGIN{RS="--\n"; FS="\n"; OFS="|"} {print $1,$2,$3}' file)

That preserves leading and trailing white spaces on each line.

If you want to strip leading and trailing white spaces, remove the IFS="|" and the OFS="|" part so that Bash strips the lines:

while read -r url name web; do
    echo "$url" "$name" "$web"
done  < <(awk 'BEGIN{RS="--\n"; FS="\n"} {print $1,$2,$3}' file)

Upvotes: 1

Charles Duffy
Charles Duffy

Reputation: 296039

With a bit of error-handling, this might look like:

while read -r url && read -r name && read -r web; do
  echo "Read url of $url, name of $name, and web of $web"
  read -r sep || { true; break; } # nothing to read: exit loop w/ successful $?
  if [[ $sep != -- ]]; then
    printf 'Expected separator, but saw: %q\n' "$sep" >&2
    false; break # "--" not seen where expected; exit loop w/ $? indicating failure
  fi
done <in.txt

See BashFAQ #1.

(By the way -- if you don't want leading and trailing whitespace stripped, I would suggest clearing IFS with IFS= -- either scoped to the reads as in while IFS= read -r url && IFS= read -r name && IFS= read -r web, or global to the script if there's nothing else going on where the side effects would be undesired).

Upvotes: 4

Mario Keller
Mario Keller

Reputation: 421

This should work for your case

    NR=0
    while read LINE; do
        ((NR++))
        case $NR in
            1)
                URL=$LINE
                    ;;
            2)
                NAME=$LINE
                    ;;
            3)
                WEB=$LINE
                    ;;
            4)
                if [ $LINE = "--" ]; then
                    NR=0
                    #
                    # DO WHAT EVER YOU WANT TO DO WITH YOUR DATA HERE
                    #
                    #
                    echo "$URL;;$NAME;;$WEB"
                else
                    echo "wrong delimiter found \"$LINE\""
                fi
                    ;;
        esac
    done

run it with

script.sh < inputfile.txt

or just pipe the output of your grep command to the script.

Upvotes: 0

Related Questions