BASH
input: cat test
1 a;b;c;d
2 a;b;c;d
3 a;b;c;d
desired output is:
1 a
1 b
1 c
1 d
2 a
2 b
2 c
Solution 1st: Could you please try following.
awk -F'[ ;]' '{for(i=2;i<=NF;i++){print $1,$i}}' Input_file
Solution 2nd: Adding another awk
too now.
awk '{gsub(/;/,ORS $1 OFS)} 1' Input_file
Straightforward shell:
IFS=" ;"
shopt noglob # or set -f
while read -r line; do
set -- $line; a=$1; shift
for b; do printf '%s %s\n' "$a" "$b"; done
done
# if data never contains backslash can omit -r from read
# if data never contains glob patterns (? * [..] etc) can omit set -f
# if data never contains backslash and first col never begins with hyphen
# can replace printf with echo "$a" "$b"
Clever shell, if first column never contains percent or backslash:
IFS=" ;"
shopt noglob # or set -f
while read -r line; do
set -- $line; a=$1; shift
printf "$a %s\n" "$@"
done
# read -r and set -f as above
Both of these leave IFS and (maybe) noglob changed; if this is all or the last part of a script, or a function using (), those changes are to a local instance and discarded. Otherwise either explicitly save and restore, or surround with () so they are discarded.
Similarly both clobber the positional arguments, which generally matters only when in a script or function; if those are needed subsequently, save and restore them, or alternatively in bash or ksh only use a separate explicit array variable:
IFS=" ;"
shopt noglob # or set -f
while read -ra ary; do
a=${ary[0]}; unset ary[0]
for b in "${ary[@]}"; do printf '%s %s\n' "$a" "$b"; done
# or
printf "$a %s\n" "${ary[@]}"
done
This might work for you (GNU sed):
sed -r 's/^((\s*\S+\s*)[^;]*);/\1\n\2/;P;D' file
Replace each ;
by a newline followed by the key.