Awk / sed / shell to merge / concatenate data

Trying to combine some of the data that I have. The input will look like this:

foo bar
foo baz boo
abc def
abc ghi

And I would like the result to look like this:

foo bar baz boo
abc def ghi

I have ideas using some arrays in a shell script, but I was looking for a more elegant or faster solution.

+3
source share
6 answers

How about joining?

file="file"
join -a1 -a2 <(sort "$file" | sed -n 1~2p) <(sort "$file" | sed -n 2~2p)

Seed is only splitting a file into odd and even lines

+3
source

While the pixel response works, I cannot say that I am very happy about this. I think I will use awk something like this:

    { for (i=2; i<=NF; i++) { lines[$1] = lines[$1] " " $i;} }  
END { for (i in lines) printf("%s%s\n", i, lines[i]); }

, (, ). , . , ( - ).

+2

awk

awk '
    {key=$1; $1=""; x[key] = x[key] $0}
    END {for (key in x) {print key x[key]}}
' filename
+2

, uniq -w. awk (: ):

awk '
    BEGIN{last='';}
    {
        if ($1==last) {
            for (i = 1; i < NF;i++) print $i;
        } else {
            print "\n", $0;
            last = $1;
        }
    }'
0

Pure Bash, :

infile="paste.dat"

toggle=0
while read -a line ; do
  if [ $toggle -eq 0 ] ; then
    echo -n "${line[@]}"
  else
    unset line[0]               # remove first element
    echo  " ${line[@]}"
  fi
  ((toggle=1-toggle))
done < "$infile"
0

fgm pure Bash snippet:

text='
foo bar
foo baz boo
abc def
abc ghi
'

count=0
oneline=""
firstword=""
while IFS=" " read -a line ; do
   let count++
   if [[ $count -eq 1 ]]; then
      firstword="${line[0]}"
      oneline="${line[@]}"
   else
      if [[ "$firstword" == "${line[0]}" ]]; then
         unset line[0] # remove first word of line
         oneline="${oneline} ${line[@]}"
      else
         printf "%s\n" "${oneline}"
         oneline="${line[@]}"
         firstword="${line[0]}"
      fi
  fi
done <<< "$text"
0

Source: https://habr.com/ru/post/1743586/


All Articles