Script suggestion

I have a file which looks like

ant1 1,2,3,4 bat1
ant1 5,6,7,8 bat2

I would like to have an O/p as

ant1 1 bat1
ant1 2 bat1
ant1 3 bat1
ant1 4 bat1
ant1 5 bat2
ant1 6 bat2
ant1 7 bat2
ant1 8 bat2

Is it possible.

Thanks for any suggestion

Just by replacing any comma with a Field Separator (FS) (here:a space) + last Field of the line ($NF) + Record Separator (RS) (here:line jump) + First field of the line ($1) + Field separator (FS) ( here a space) which gives :

$ cat mytst
ant1 1,2,3,4 bat1
ant1 5,6,7,8 bat2
$ awk '{c=FS$NF RS$1FS;gsub(/,/,c,$0)}1' mytst
ant1 1 bat1
ant1 2 bat1
ant1 3 bat1
ant1 4 bat1
ant1 5 bat2
ant1 6 bat2
ant1 7 bat2
ant1 8 bat2
1 Like

Many many thanks

Hi,

Here is without other text utilities:

#!/bin/bash

while read a b c 
do
IFS=$','
for i in $b
do
echo $a $i $c
done
IFS=$' '
done < file
1 Like

Hi, more short in bash:

while read a b c
do
  printf "$a %s $b\n" ${b//,/ }
done < file

Regards.

I guess you meant to write

printf "$a %s $c\n" ${b//,/ }
1 Like

Hi,

@ disedorgue: I found that ,

${string//substring/replacement}
Replace all matches of substring with replacement.

For example, ${b//,/} deletes all comma which is ok.

I still couldnt follow how ${b//,/ } works like a loop to give numbers one by one ?

Can you explain how it works or link for more information ?

Hi greet_sed,
${b//,/ } is just to pass $b several arguments to printf...
Under bash (explanation in red):

$ help printf
printf: printf [-v var] format [arguments]
    Formats and prints ARGUMENTS under control of the FORMAT.
    
    Options:
      -v var	assign the output to shell variable VAR rather than
    		display it on the standard output
    
    FORMAT is a character string which contains three types of objects: plain
    characters, which are simply copied to standard output; character escape
    sequences, which are converted and copied to the standard output; and
    format specifications, each of which causes printing of the next successive
    argument.
    
    In addition to the standard format specifications described in printf(1),
    printf interprets:
    
      %b	expand backslash escape sequences in the corresponding argument
      %q	quote the argument in a way that can be reused as shell input
      %(fmt)T output the date-time string resulting from using FMT as a format
            string for strftime(3)
    
    The format is re-used as necessary to consume all of the arguments.  If
    there are fewer arguments than the format requires,  extra format
    specifications behave as if a zero value or null string, as appropriate,
    had been supplied.
    
    Exit Status:
    Returns success unless an invalid option is given or a write or assignment
    error occurs.

Regards.

2 Likes

"The format is re-used as necessary to consume all of the arguments."
This trick repeats the format (which makes a line).
Unfortunately the variables in the format string must not contain % characters that have special meaning in the format.

---------- Post updated at 01:56 ---------- Previous update was at 01:47 ----------

Another example with an explicit for loop; the scope of the manipulated IFS (input field separator) is limited to the ( subshell ) .

while read a b c 
do
(
IFS=','
for i in $b
do
echo "$a $i $c"
done
)
done < file
1 Like

Just replace % by %% :

$ cat ooo
ant1 1,2,3,4 bat1
ant1 5,6,7,8 bat2
a%c%s 6,%c,9,0 a%d%%o2
$ while read a b c; do   printf "${a//%/%%} %s ${c//%/%%}\n" ${b//,/ }; done <ooo
ant1 1 bat1
ant1 2 bat1
ant1 3 bat1
ant1 4 bat1
ant1 5 bat2
ant1 6 bat2
ant1 7 bat2
ant1 8 bat2
a%c%s 6 a%d%%o2
a%c%s %c a%d%%o2
a%c%s 9 a%d%%o2
a%c%s 0 a%d%%o2

Regards.

1 Like