Shell command to transpose Row & Column

Hi all,

need a help with getting a one line command to do the following.
i have an input file with rows of data containing credits for each office, the output should be one row for each office with all the credits in rows for that office, if its not there then it should say N/A. the credits are fixed according to the office to 4.
Appreciate your help.

Input:

Region	State	City	Office	credit
SE	Georgia	Atlanta	Admin	92
SE	Georgia	Atlanta	HR	45
SE	Georgia	Atlanta	Tech	150
SE	Georgia	Atlanta	Soft	250
MW	Texas	Dallas	Admin	400
MW	Texas	Dallas	Tech	121

Output:

Region	State	City	Admin	HR	Tech	Soft
SE	Georgia	Atlanta	92	45	150	250
MW	Texas	Dallas	400	N/A	121	N/A

Assuming this is homework because of your written condition - "one line command". If this is a real problem, please explain and also include what you have tried.

Do not post classroom or homework problems in the main forums. Homework and coursework questions can only be posted in this forum under special homework rules.

Please review the rules, which you agreed to when you registered, if you have not already done so.

More-than-likely, posting homework in the main forums has resulting in a forum infraction. If you did not post homework, please explain the company you work for and the nature of the problem you are working on.

If you did post homework in the main forums, please review the guidelines for posting homework and repost.

Thank You.

The UNIX and Linux Forums.

How far would this (admittedly clumsy) approach get you?

awk '
        {CAT[$1,$2,$3] = NR
         OFF[$4] = NR
         T[$1,$2,$3,$4] = $5
        }

END     {for (c in CAT) {printf "%s", c
                         for (o in OFF) if (OFF[o]!=1) printf "\t%s", CAT[c]==1?o:T[c,o]?T[c,o]:"N/A"
                         printf RS
                        }
        }
' SUBSEP="\t" file
Region	State	City	Soft	Admin	HR	Tech
MW	Texas	Dallas	N/A	400	N/A	121
SE	Georgia	Atlanta	250	92	45	150

sorry for the late reply, this is definitely not homework.
i work on cisco platform, with some files having data close to what i asked for.
the reason i asked for a one liner is coz it needs to be incorporated in already existing script.
This is what i tried so far with no luck.

perl -ane 'BEGIN{$lc=0;} if ($lc==0) {@r=@F;$lc++;} else {for $i (1 .. $#r) {print "$F[0]\t$r[$i]\t$F[$i]\n";}$lc=0;@r=();}' sample.txt
SE      State   Georgia
SE      City    Atlanta
SE      Office  Admin
SE      credit  92
SE      Georgia Georgia
SE      Atlanta Atlanta
SE      HR      Tech
SE      45      150
MW      Georgia Texas
MW      Atlanta Dallas
MW      Soft    Admin
MW      250     400

See post#3

1 Like

thank you rudic but iam getting the following error.

awk: {CAT[$1,$2,$3]=NR OFF[$4]=NR T[$1,$2,$3,$4]=$5} END {for (c in CAT) {printf "%s", c for (o in OFF) if (OFF[o]!=1) printf "\t%s", CAT[c]==1?o:T[c,o]?T[c,o]:"N/A" printf RS}}
awk:                          ^ syntax error
awk: {CAT[$1,$2,$3]=NR OFF[$4]=NR T[$1,$2,$3,$4]=$5} END {for (c in CAT) {printf "%s", c for (o in OFF) if (OFF[o]!=1) printf "\t%s", CAT[c]==1?o:T[c,o]?T[c,o]:"N/A" printf RS}}
awk:                                            ^ syntax error
awk: {CAT[$1,$2,$3]=NR OFF[$4]=NR T[$1,$2,$3,$4]=$5} END {for (c in CAT) {printf "%s", c for (o in OFF) if (OFF[o]!=1) printf "\t%s", CAT[c]==1?o:T[c,o]?T[c,o]:"N/A" printf RS}}
awk:                                                                                     ^ syntax error

You should NOT modify the structure of a script / program without knowing EXACTLY what you're doing.
When shoving all of the lines of a structured / indented file into one single line, you AT LEAST need to insert semicolons instead of the line breaks.

thank you rudic it worked. appreciate your help.

You can incorporate many-liners as well as one-liners into existing scripts:

...
var=$(cmd1 | sed '<one-line-here>' | cmd2)
...

or several lines like this. Notice the punctuation and that the indentation makes it easier to discern what belongs to where. The same goes for any text filter other than sed (awk, grep, ...) too:

...
var=$( \
       cmd1 |\
       sed '<one-line>
            <next-line>
            <etc.>' |\
       cmd2 \
)
...

I write programs in some form for 40 years now. I found that, as a rule of thumb, lines longer than 80 characters are usually wrong. Even if they aren't they are hard to read and should be avoided. Here is a real example from one of my scripts:

sed 's/[^\]#.*$//
     s/^#.*$//
     s/\\#/#/g
     /^[        ]*$/d
     s/[        ]*$//
     s/^/x/' "$fInFile" |\
while read chLine ; do
     chItem=""
     chValue=""
     ...

Readable, no? Here is the one-liner-version:

sed 's/[^\]#.*$//;s/^#.*$//;s/\\#/#/g;/^[        ]*$/d;s/[        ]*$//;s/^/x/' "$fInFile"|while read chLine;do;chItem="";chValue="";...

Probably not quite easy to decipher, is it?

I hope this helps.

bakunin

Note: in this case the newline escapes ( \ ) can be omitted:

...
var=$( 
       cmd1 |
       sed '<one-line>
            <next-line>
            <etc.>' |
       cmd2
)
...