Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to transpose few rows to column using awk or sed

Tags:

linux

unix

sed

awk

tr

I want to bring some of the data in a row to the side column of the current column,. Chunk 1 and chunk 2 of the column are separated by a new line. How can I do it.

Cat filename
aaa
bbb
ccc
ddd

eee
fff
ggg
hhh


cat desiredFile
aaa eee
bbb fff
ccc ggg
ddd hhh

2 Answers

There are many ways. A simple one using bash, paste, and GNU sed is

paste -d ' ' <(sed '/^$/Q' filename) <(sed '0,/^$/d' filename)

Here

  • sed '/^$/Q' filename prints all lines in the file up to the first empty line
  • sed '0,/^$/d' filename prints all lines after the first empty line
  • <() is a bash-specific process substitution that expands to the name of a pipe from which the output of the command can be read (so that it can be used as an input filename), and
  • paste -d ' ' file1 file2 pastes two files together in the manner you described (delimited by a space because of -d ' '; without that option it would use a tab)

Or you could use awk:

awk -v RS="" -F '\n' 'NF > n { n = NF } { for(i = 1; i <= NF; ++i) a[i] = a[i] OFS $i } END { for(i = 1; i <= n; ++i) print a[i] }' filename

With an empty RS, awk splits the file into records at the empty line, with -F '\n' it splits those records into fields at newlines, and then the code is

# remember maximum number of fields encountered
NF > n { n = NF }

# wade through the fields, assemble the output lines from them
{ for(i = 1; i <= NF; ++i) a[i] = a[i] OFS $i }

# in the end, print the assembled lines.
END { for(i = 1; i <= n; ++i) print a[i] }

The advantage of the awk approach is that it'll work with more than two chunks of lines.

like image 170
Wintermute Avatar answered Dec 10 '25 18:12

Wintermute


Ruby is handy for one-liners, and it has a builtin transpose method. Using a similar approach to Wintermute, we have:

ruby -00 -F"\n" -ane '
    BEGIN {data=[]}
    data << $F
    END {data.transpose.each {|row| puts row.join(" ")}}
' file

I added another paragraph to the test file, and it outputs this:

aaa eee iii
bbb fff jjj
ccc ggg kkk
ddd hhh lll
like image 44
glenn jackman Avatar answered Dec 10 '25 20:12

glenn jackman