Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The characteristics of the input data:

  • Each line consists of two fields, separated by a pipe '|', where
  • the first field is a comma-separated list of items, and
  • the second field is a tag.




share|improve this question

closed as too localized by manatwork, Renan, warl0ck, jw013, derobert Oct 9 '12 at 16:46

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

Assuming the items contain no “|” and the tags contain no “,”:

awk -F '[,|]' '{for(i=1;i<NF;i++)print$i$NF}' input.txt
share|improve this answer
Nice! I did not know you could give multiple field separators to gawk. – terdon Oct 9 '12 at 10:49
@terdon you can use any (awk-compatible) regular expression for the separator. – Kevin Oct 9 '12 at 12:39

Will PERL do?

$ perl -ne 'chomp; @a=split(/\|/); @b=split(/,/,$a[0]); map{print "$_$a[1]\n"}@b' input.txt
share|improve this answer

Pure sed solution:

sed ':a;s/\(.*\),\([^,]*\)|\(.*\)/\2\3\n\1|\3/;ta;s/|//' input.file
share|improve this answer

And now, in bash and sed only:

cat test.txt| while IFS="|" read i t ; do echo $i | sed "s/\([0-9]\+\)/\1$t/g;s/,/\n/g" ; done

And in bash only (courtesy Nahuel Fouilleul):

 while IFS="|" read i t;do while read -d, j;do echo "$j$t";done <<<"$i,";done <test.txt
share|improve this answer
Still not bash only due to the UUOC (Useless Use of cat). – manatwork Oct 9 '12 at 12:30
$t and \1 should be swapped in sed. – Thor Oct 9 '12 at 12:38
full bash version : while IFS="|" read i t;do while read -d, j;do echo "$j$t";done <<<"$i,";done <test.txt, may be more efficient on small files but for larger files awk will be a better choice – Nahuel Fouilleul Oct 9 '12 at 12:41


sed -e 's/^\([0-9][0-9]*\),.*|\(.*\)/\1\2/'

if the first field isn't numeric, then it can be changed to something like

sed -e 's/^\([^,][^,]*\),.*|\(.*\)/\1\2/'
share|improve this answer
This will only produce the first item-tag pair. – January Oct 9 '12 at 11:45
Oh yes - I missed that part of it! – Julian Oct 10 '12 at 8:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.