JohnnyF
JohnnyF

Reputation: 1101

Parsing text in bash script

i have this text

hello world@helloworld@/dev/zero@inout/helloworld.out
hello world with warnings@warnings@/dev/zero@inout/helloworld.out
echo test@myecho@inout/echo.in@inout/echo.out
echo failtest@myecho@inout/echo.in@inout/helloworld.out
memleaks pass@memleaks@inout/memleaks.6.in@inout/memleaks.6.out
memleaks fail@memleaks@inout/memleaks.11.in@inout/memleaks.11.out

i want to run a bash loop that in each run i will read one line and will get 4 vars each untill the @ (without the @) and to know what line number i am i got so far

(( index=0 ))
for read line
do
    (( index+=1 ))
    var1=
    var2=
    var3=
    var4=
done

what i want to get is

var1=hello world
var2=helloworld
var3=/dev/zero
var4=inout/helloworld.out

and is there a way to do it in 1 line?

Upvotes: 0

Views: 1020

Answers (2)

yossarian
yossarian

Reputation: 1667

You can also do this in awk with the -F flag, which specifies a field separator (equivalent to $IFS).

For example, to dump the fields in each line:

while read line ; do
  echo $line | awk -F '@' '{ print $1,$2,$3,$4 }'
done

Upvotes: 0

tripleee
tripleee

Reputation: 189397

Bash (obviously) has file reading and token splitting build in. To split on a custom separator, set IFS to a suitable value.

oldIFS=$IFS
IFS=@
while read -r var1 var2 var3 var4; do
    : stuff
done <file

You need oldIFS if anything else in your script depends on the regular whitespace-solitting behavior. A common arrangement is to put the splitting in a function with a local value for IFS.

The -r option to read specifies sane behavior and should be default, but can't be for legacy reasons. The behavior without this option makes sense if you are parsing actual shell code, but not generally.

Upvotes: 1

Related Questions