Transposing rows and columns

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












14















I have a file with the lines like below.



title1:A1
title2:A2
title3:A3
title4:A4
title5:A5

title1:B1
title2:B2
title3:B3
title4:B4
title5:B5

title1:C1
title2:C2
title3:C3
title4:C4
title5:C5

title1:D1
title2:D2
title3:D3
title4:D4
title5:D5


How can I achieve this?




title1 title2 title3 title4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
D1 D2 D3 D4









share|improve this question
























  • please please please don't use awk, you might as well roll a custom solution with perl or python or a real programming language or use tr/cut with multiple passes to get what you want

    – Rudolf Olah
    May 30 '16 at 16:47















14















I have a file with the lines like below.



title1:A1
title2:A2
title3:A3
title4:A4
title5:A5

title1:B1
title2:B2
title3:B3
title4:B4
title5:B5

title1:C1
title2:C2
title3:C3
title4:C4
title5:C5

title1:D1
title2:D2
title3:D3
title4:D4
title5:D5


How can I achieve this?




title1 title2 title3 title4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
D1 D2 D3 D4









share|improve this question
























  • please please please don't use awk, you might as well roll a custom solution with perl or python or a real programming language or use tr/cut with multiple passes to get what you want

    – Rudolf Olah
    May 30 '16 at 16:47













14












14








14


7






I have a file with the lines like below.



title1:A1
title2:A2
title3:A3
title4:A4
title5:A5

title1:B1
title2:B2
title3:B3
title4:B4
title5:B5

title1:C1
title2:C2
title3:C3
title4:C4
title5:C5

title1:D1
title2:D2
title3:D3
title4:D4
title5:D5


How can I achieve this?




title1 title2 title3 title4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
D1 D2 D3 D4









share|improve this question
















I have a file with the lines like below.



title1:A1
title2:A2
title3:A3
title4:A4
title5:A5

title1:B1
title2:B2
title3:B3
title4:B4
title5:B5

title1:C1
title2:C2
title3:C3
title4:C4
title5:C5

title1:D1
title2:D2
title3:D3
title4:D4
title5:D5


How can I achieve this?




title1 title2 title3 title4
A1 A2 A3 A4
B1 B2 B3 B4
C1 C2 C3 C4
D1 D2 D3 D4






text-processing columns






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 17 '13 at 2:43









jasonwryan

49.6k14134185




49.6k14134185










asked Jun 17 '13 at 2:13









DensDens

71113




71113












  • please please please don't use awk, you might as well roll a custom solution with perl or python or a real programming language or use tr/cut with multiple passes to get what you want

    – Rudolf Olah
    May 30 '16 at 16:47

















  • please please please don't use awk, you might as well roll a custom solution with perl or python or a real programming language or use tr/cut with multiple passes to get what you want

    – Rudolf Olah
    May 30 '16 at 16:47
















please please please don't use awk, you might as well roll a custom solution with perl or python or a real programming language or use tr/cut with multiple passes to get what you want

– Rudolf Olah
May 30 '16 at 16:47





please please please don't use awk, you might as well roll a custom solution with perl or python or a real programming language or use tr/cut with multiple passes to get what you want

– Rudolf Olah
May 30 '16 at 16:47










9 Answers
9






active

oldest

votes


















12














Have a look at GNU datamash which can be used like datamash transpose.
A future version will also support cross tabulation (pivot tables)






share|improve this answer






























    8














    You could use awk to process the data then paste and column to format it.



    Here I assume title1 is only an example in your post, and that data does not contain : except as separator between header + data.



    n signifies how many columns to print (should match dashes in paste).



    awk -F":" -v n=4 
    'BEGIN x=1; c=0;
    ++c <= n && x == 1 print $1; buf = buf $2 "n";
    if(c == n) x = 2; printf buf next;
    !/./c=0;next
    c <=n printf "%sn", $2' datafile |
    paste - - - - |
    column -t -s "$(printf "t")"



    If you want to make it more flexible and easy to maintain you could write it as a script. Here is an example using bash wrapper for awk and piped to column. This way you could also do more data checking like e.g. making sure headers is correct throughout all rows etc.



    Used typically as:



    $ ./trans -f data -c 4
    title one title two title three title four
    A1 A2 A3 A4
    B1 B2 B3 B4
    C1 C2 C3 C4
    D1 D2 D3 D4


    If headers always is shorter then data you could also save header widths, then printf with %-*s and skip column all together.



    #!/bin/bash

    trans()

    awk -F":" -v ncol="$1" '
    BEGIN
    level = 1 # Run-level.
    col = 1 # Current column.
    short = 0 # If requested to many columns.

    # Save headers and data for row one.
    level == 1
    head[col] = $1
    data[col] = $2
    if (++col > ncol) # We have number of requested columns.
    level = 2
    else if ($0 == "") # If request for more columns then available.
    level = 2
    ncol = col - 2
    short = 1
    else
    next


    # Print headers and row one.
    level == 2
    for (i = 1; i <= ncol; ++i)
    printf("%st", head[i])
    print ""
    for (i = 1; i <= ncol; ++i)
    printf("%st", data[i])
    level = 3
    col = ncol + 1
    if (!short)
    next

    # Empty line, new row.
    ! /./ print ""; col = 1; next
    # Next cell.
    col > ncol next

    printf "%s%s", $2, (col <= ncol) ? "t" : ""
    ++col

    END print ""
    ' "$2"


    declare -i ncol=4 # Columns defaults to four.
    file="" # Data file (or pipe).

    while [[ -n "$1" ]]; do
    case "$1" in
    "-c") ncol="$2"; shift;;
    "-f") file="$2"; shift;;
    *) printf "Usage: %s [-c <columns>] [-f <file> | pipe]n"
    "$(basename $0)" >&2;
    exit;;
    esac
    shift
    done

    trans "$ncol" "$file" | column -t -s "$(printf "t")"





    share|improve this answer




















    • 1





      Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

      – slm
      Jun 17 '13 at 11:19


















    8














    Outside of rolling a custom solution to transpose rows with columns from a command line the only tool I've ever seen that can do this is a tool called ironically transpose.



    Installation



    Unfortunately it's not in any repo so you'll need to download and compile it. This is pretty straightforward since it has no additional libraries that it's dependent on. It can be accomplished like so:



    $ gcc transpose.c -o transpose


    Usage



    It can handle straightforward text files with ease. For example:



    $ cat simple.txt 
    X column1 column2 column3
    row1 0 1 2
    row2 3 4 5
    row3 6 7 8
    row4 9 10 11


    Can be transposed using this command:



    $ transpose -t --fsep " " simple.txt 
    X row1 row2 row3 row4
    column1 0 3 6 9
    column2 1 4 7 10
    column3 2 5 8 11


    This command is transpose to transpose (-t) and the field separator to use is a space (--fsep " ").



    Your example



    Since your sample data is in a slightly more complex format it needs to be dealt with in 2 phases. First we need to translate it into a format that transpose can deal with.



    Running this command, will put the data in a more horizontally friendly format:



    $ sed 's/:/ /; /^$/d' sample.txt 
    | sort | paste - - - - -
    title1 A1 title1 B1 title1 C1 title1 D1 title2 A2
    title2 B2 title2 C2 title2 D2 title3 A3 title3 B3
    title3 C3 title3 D3 title4 A4 title4 B4 title4 C4
    title4 D4 title5 A5 title5 B5 title5 C5 title5 D5


    Now we just need to remove the secondary occurrences of the title1, title2, etc.:



    $ sed 's/:/ /; /^$/d' sample.txt 
    | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
    title1 A1 B1 C1 D1 A2
    title2 B2 C2 D2 A3 B3
    title3 C3 D3 A4 B4 C4
    title4 D4 A5 B5 C5 D5


    It's now in a format that transpose can deal with. The following command will do the entire transposition:



    $ sed 's/:/ /; /^$/d' sample.txt 
    | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
    | transpose -t --fsep " "
    title1 title2 title3 title4
    A1 B2 C3 D4
    B1 C2 D3 A5
    C1 D2 A4 B5
    D1 A3 B4 C5
    A2 B3 C4 D5





    share|improve this answer






























      7














      Here's a quick way to put the file into the format you want:



      $ grep -Ev "^$|title5" sample.txt | sed 's/title[0-9]://g' | paste - - - -
      A1 A2 A3 A4
      B1 B2 B3 B4
      C1 C2 C3 C4
      D1 D2 D3 D4


      If you want the column headers:



      $ grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't'; 
      echo "";
      grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -
      title1 title2 title3 title4
      A1 A2 A3 A4
      B1 B2 B3 B4
      C1 C2 C3 C4
      D1 D2 D3 D4


      How the 2nd command works



      printing the banner

      grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't';


      putting a return after the banner in

      echo


      printing the rows of data

      grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -





      share|improve this answer

























      • paste command simply made my job done. thanks for the answer...

        – S.K. Venkat
        Jul 22 '17 at 12:21


















      3














      There's probably a more succinct way of formulating this but this seems to accomplish the general effect:



      [jadavis84@localhost ~]$ sed 's/^title[2-9]://g' file.txt | tr 'n' 't' | sed 's/title1:/n/g' ; echo

      A1 A2 A3 A4 A5
      B1 B2 B3 B4 B5
      C1 C2 C3 C4 C5
      D1 D2 D3 D4 D5
      [jadavis84@localhost ~]$


      Multiple sed invocations doesn't feel right (and I'm pretty sure sed can do the new line translation as well) so it probably isn't the most straight forward way to do it. Also, this strips the would-be headers, but you can generate those manually once you have the rows/fields formatted properly.



      A better answer would probably distill that effect down to just using sed or awk to do this so that you only have one thing going on at a time. But I'm tired so this is what I was able to put together.






      share|improve this answer























      • Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

        – slm
        Jun 17 '13 at 3:23











      • Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

        – Bratchley
        Jun 17 '13 at 11:13


















      3














      GNU datamash utility



      apt install datamash 

      datamash transpose < yourfile


      Taken from this site, https://www.gnu.org/software/datamash/ and http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods






      share|improve this answer






























        1














        paste is probably your best bet. You can extract the relevant bits with cut, grep and awk like this:



        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile)


        If the 5th column should be eliminated, append awk 'NR%5' like this:



        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5'


        Now columnate with paste:



        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5' | paste - - - -


        Output:



        title1 title2 title3 title4
        A1 A2 A3 A4
        B1 B2 B3 B4
        C1 C2 C3 C4
        D1 D2 D3 D4





        share|improve this answer






























          0














          For just the transpose part, I had a similar problem recently and used:



          awk -v fmt='t%4s' ' for(i=1;i<=NF;i++) a[i]=a[i] sprintf(fmt, $i); END for (i in a) print a[i]; '


          Adjust the fmt as needed. For each input line, it concatenates each fields onto an array element. Note that awk string concatenation is implicit: it happens when you write two things without any operator.



          Sample I/O:



          i mark accep igna utaal bta
          -22 -10 -10 -20 -10 -10
          -21 -10 -10 -20 -10 -10
          -20 -10 -10 -20 -10 -10
          -19 -10 0 -10 -10 -10
          -18 0 0 -10 0 0
          -12 0 0 -10 0 0
          -11 0 0 -10 0 0
          -10 0 0 -10 0 0


          output:



           i -22 -21 -20 -19 -18 -12 -11 -10
          mark -10 -10 -10 -10 0 0 0 0
          accep -10 -10 -10 0 0 0 0 0
          igna -20 -20 -20 -10 -10 -10 -10 -10
          utaal -10 -10 -10 -10 0 0 0 0
          bta -10 -10 -10 -10 0 0 0 0





          share|improve this answer
































            -1














            The simplest thing you can do is to use cut to cut the fields and then use tr if you're transposing rows to columns by replacing the newline character with a tab character: http://www.gnu.org/software/coreutils/manual/coreutils.html#tr-invocation



            cat file.txt | cut -d':' | tr 'n' 't'





            share|improve this answer























            • Without a list of fields, cut returns an error.

              – agc
              Jul 13 '16 at 13:28










            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f79642%2ftransposing-rows-and-columns%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            9 Answers
            9






            active

            oldest

            votes








            9 Answers
            9






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            12














            Have a look at GNU datamash which can be used like datamash transpose.
            A future version will also support cross tabulation (pivot tables)






            share|improve this answer



























              12














              Have a look at GNU datamash which can be used like datamash transpose.
              A future version will also support cross tabulation (pivot tables)






              share|improve this answer

























                12












                12








                12







                Have a look at GNU datamash which can be used like datamash transpose.
                A future version will also support cross tabulation (pivot tables)






                share|improve this answer













                Have a look at GNU datamash which can be used like datamash transpose.
                A future version will also support cross tabulation (pivot tables)







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 7 '16 at 9:06









                Pádraig BradyPádraig Brady

                1,7231211




                1,7231211























                    8














                    You could use awk to process the data then paste and column to format it.



                    Here I assume title1 is only an example in your post, and that data does not contain : except as separator between header + data.



                    n signifies how many columns to print (should match dashes in paste).



                    awk -F":" -v n=4 
                    'BEGIN x=1; c=0;
                    ++c <= n && x == 1 print $1; buf = buf $2 "n";
                    if(c == n) x = 2; printf buf next;
                    !/./c=0;next
                    c <=n printf "%sn", $2' datafile |
                    paste - - - - |
                    column -t -s "$(printf "t")"



                    If you want to make it more flexible and easy to maintain you could write it as a script. Here is an example using bash wrapper for awk and piped to column. This way you could also do more data checking like e.g. making sure headers is correct throughout all rows etc.



                    Used typically as:



                    $ ./trans -f data -c 4
                    title one title two title three title four
                    A1 A2 A3 A4
                    B1 B2 B3 B4
                    C1 C2 C3 C4
                    D1 D2 D3 D4


                    If headers always is shorter then data you could also save header widths, then printf with %-*s and skip column all together.



                    #!/bin/bash

                    trans()

                    awk -F":" -v ncol="$1" '
                    BEGIN
                    level = 1 # Run-level.
                    col = 1 # Current column.
                    short = 0 # If requested to many columns.

                    # Save headers and data for row one.
                    level == 1
                    head[col] = $1
                    data[col] = $2
                    if (++col > ncol) # We have number of requested columns.
                    level = 2
                    else if ($0 == "") # If request for more columns then available.
                    level = 2
                    ncol = col - 2
                    short = 1
                    else
                    next


                    # Print headers and row one.
                    level == 2
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", head[i])
                    print ""
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", data[i])
                    level = 3
                    col = ncol + 1
                    if (!short)
                    next

                    # Empty line, new row.
                    ! /./ print ""; col = 1; next
                    # Next cell.
                    col > ncol next

                    printf "%s%s", $2, (col <= ncol) ? "t" : ""
                    ++col

                    END print ""
                    ' "$2"


                    declare -i ncol=4 # Columns defaults to four.
                    file="" # Data file (or pipe).

                    while [[ -n "$1" ]]; do
                    case "$1" in
                    "-c") ncol="$2"; shift;;
                    "-f") file="$2"; shift;;
                    *) printf "Usage: %s [-c <columns>] [-f <file> | pipe]n"
                    "$(basename $0)" >&2;
                    exit;;
                    esac
                    shift
                    done

                    trans "$ncol" "$file" | column -t -s "$(printf "t")"





                    share|improve this answer




















                    • 1





                      Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

                      – slm
                      Jun 17 '13 at 11:19















                    8














                    You could use awk to process the data then paste and column to format it.



                    Here I assume title1 is only an example in your post, and that data does not contain : except as separator between header + data.



                    n signifies how many columns to print (should match dashes in paste).



                    awk -F":" -v n=4 
                    'BEGIN x=1; c=0;
                    ++c <= n && x == 1 print $1; buf = buf $2 "n";
                    if(c == n) x = 2; printf buf next;
                    !/./c=0;next
                    c <=n printf "%sn", $2' datafile |
                    paste - - - - |
                    column -t -s "$(printf "t")"



                    If you want to make it more flexible and easy to maintain you could write it as a script. Here is an example using bash wrapper for awk and piped to column. This way you could also do more data checking like e.g. making sure headers is correct throughout all rows etc.



                    Used typically as:



                    $ ./trans -f data -c 4
                    title one title two title three title four
                    A1 A2 A3 A4
                    B1 B2 B3 B4
                    C1 C2 C3 C4
                    D1 D2 D3 D4


                    If headers always is shorter then data you could also save header widths, then printf with %-*s and skip column all together.



                    #!/bin/bash

                    trans()

                    awk -F":" -v ncol="$1" '
                    BEGIN
                    level = 1 # Run-level.
                    col = 1 # Current column.
                    short = 0 # If requested to many columns.

                    # Save headers and data for row one.
                    level == 1
                    head[col] = $1
                    data[col] = $2
                    if (++col > ncol) # We have number of requested columns.
                    level = 2
                    else if ($0 == "") # If request for more columns then available.
                    level = 2
                    ncol = col - 2
                    short = 1
                    else
                    next


                    # Print headers and row one.
                    level == 2
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", head[i])
                    print ""
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", data[i])
                    level = 3
                    col = ncol + 1
                    if (!short)
                    next

                    # Empty line, new row.
                    ! /./ print ""; col = 1; next
                    # Next cell.
                    col > ncol next

                    printf "%s%s", $2, (col <= ncol) ? "t" : ""
                    ++col

                    END print ""
                    ' "$2"


                    declare -i ncol=4 # Columns defaults to four.
                    file="" # Data file (or pipe).

                    while [[ -n "$1" ]]; do
                    case "$1" in
                    "-c") ncol="$2"; shift;;
                    "-f") file="$2"; shift;;
                    *) printf "Usage: %s [-c <columns>] [-f <file> | pipe]n"
                    "$(basename $0)" >&2;
                    exit;;
                    esac
                    shift
                    done

                    trans "$ncol" "$file" | column -t -s "$(printf "t")"





                    share|improve this answer




















                    • 1





                      Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

                      – slm
                      Jun 17 '13 at 11:19













                    8












                    8








                    8







                    You could use awk to process the data then paste and column to format it.



                    Here I assume title1 is only an example in your post, and that data does not contain : except as separator between header + data.



                    n signifies how many columns to print (should match dashes in paste).



                    awk -F":" -v n=4 
                    'BEGIN x=1; c=0;
                    ++c <= n && x == 1 print $1; buf = buf $2 "n";
                    if(c == n) x = 2; printf buf next;
                    !/./c=0;next
                    c <=n printf "%sn", $2' datafile |
                    paste - - - - |
                    column -t -s "$(printf "t")"



                    If you want to make it more flexible and easy to maintain you could write it as a script. Here is an example using bash wrapper for awk and piped to column. This way you could also do more data checking like e.g. making sure headers is correct throughout all rows etc.



                    Used typically as:



                    $ ./trans -f data -c 4
                    title one title two title three title four
                    A1 A2 A3 A4
                    B1 B2 B3 B4
                    C1 C2 C3 C4
                    D1 D2 D3 D4


                    If headers always is shorter then data you could also save header widths, then printf with %-*s and skip column all together.



                    #!/bin/bash

                    trans()

                    awk -F":" -v ncol="$1" '
                    BEGIN
                    level = 1 # Run-level.
                    col = 1 # Current column.
                    short = 0 # If requested to many columns.

                    # Save headers and data for row one.
                    level == 1
                    head[col] = $1
                    data[col] = $2
                    if (++col > ncol) # We have number of requested columns.
                    level = 2
                    else if ($0 == "") # If request for more columns then available.
                    level = 2
                    ncol = col - 2
                    short = 1
                    else
                    next


                    # Print headers and row one.
                    level == 2
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", head[i])
                    print ""
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", data[i])
                    level = 3
                    col = ncol + 1
                    if (!short)
                    next

                    # Empty line, new row.
                    ! /./ print ""; col = 1; next
                    # Next cell.
                    col > ncol next

                    printf "%s%s", $2, (col <= ncol) ? "t" : ""
                    ++col

                    END print ""
                    ' "$2"


                    declare -i ncol=4 # Columns defaults to four.
                    file="" # Data file (or pipe).

                    while [[ -n "$1" ]]; do
                    case "$1" in
                    "-c") ncol="$2"; shift;;
                    "-f") file="$2"; shift;;
                    *) printf "Usage: %s [-c <columns>] [-f <file> | pipe]n"
                    "$(basename $0)" >&2;
                    exit;;
                    esac
                    shift
                    done

                    trans "$ncol" "$file" | column -t -s "$(printf "t")"





                    share|improve this answer















                    You could use awk to process the data then paste and column to format it.



                    Here I assume title1 is only an example in your post, and that data does not contain : except as separator between header + data.



                    n signifies how many columns to print (should match dashes in paste).



                    awk -F":" -v n=4 
                    'BEGIN x=1; c=0;
                    ++c <= n && x == 1 print $1; buf = buf $2 "n";
                    if(c == n) x = 2; printf buf next;
                    !/./c=0;next
                    c <=n printf "%sn", $2' datafile |
                    paste - - - - |
                    column -t -s "$(printf "t")"



                    If you want to make it more flexible and easy to maintain you could write it as a script. Here is an example using bash wrapper for awk and piped to column. This way you could also do more data checking like e.g. making sure headers is correct throughout all rows etc.



                    Used typically as:



                    $ ./trans -f data -c 4
                    title one title two title three title four
                    A1 A2 A3 A4
                    B1 B2 B3 B4
                    C1 C2 C3 C4
                    D1 D2 D3 D4


                    If headers always is shorter then data you could also save header widths, then printf with %-*s and skip column all together.



                    #!/bin/bash

                    trans()

                    awk -F":" -v ncol="$1" '
                    BEGIN
                    level = 1 # Run-level.
                    col = 1 # Current column.
                    short = 0 # If requested to many columns.

                    # Save headers and data for row one.
                    level == 1
                    head[col] = $1
                    data[col] = $2
                    if (++col > ncol) # We have number of requested columns.
                    level = 2
                    else if ($0 == "") # If request for more columns then available.
                    level = 2
                    ncol = col - 2
                    short = 1
                    else
                    next


                    # Print headers and row one.
                    level == 2
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", head[i])
                    print ""
                    for (i = 1; i <= ncol; ++i)
                    printf("%st", data[i])
                    level = 3
                    col = ncol + 1
                    if (!short)
                    next

                    # Empty line, new row.
                    ! /./ print ""; col = 1; next
                    # Next cell.
                    col > ncol next

                    printf "%s%s", $2, (col <= ncol) ? "t" : ""
                    ++col

                    END print ""
                    ' "$2"


                    declare -i ncol=4 # Columns defaults to four.
                    file="" # Data file (or pipe).

                    while [[ -n "$1" ]]; do
                    case "$1" in
                    "-c") ncol="$2"; shift;;
                    "-f") file="$2"; shift;;
                    *) printf "Usage: %s [-c <columns>] [-f <file> | pipe]n"
                    "$(basename $0)" >&2;
                    exit;;
                    esac
                    shift
                    done

                    trans "$ncol" "$file" | column -t -s "$(printf "t")"






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jun 17 '13 at 11:32

























                    answered Jun 17 '13 at 10:41









                    RuniumRunium

                    18.3k43060




                    18.3k43060







                    • 1





                      Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

                      – slm
                      Jun 17 '13 at 11:19












                    • 1





                      Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

                      – slm
                      Jun 17 '13 at 11:19







                    1




                    1





                    Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

                    – slm
                    Jun 17 '13 at 11:19





                    Nice answer! @JoelDavis and I have been hacking on this, but your answer is terrific!

                    – slm
                    Jun 17 '13 at 11:19











                    8














                    Outside of rolling a custom solution to transpose rows with columns from a command line the only tool I've ever seen that can do this is a tool called ironically transpose.



                    Installation



                    Unfortunately it's not in any repo so you'll need to download and compile it. This is pretty straightforward since it has no additional libraries that it's dependent on. It can be accomplished like so:



                    $ gcc transpose.c -o transpose


                    Usage



                    It can handle straightforward text files with ease. For example:



                    $ cat simple.txt 
                    X column1 column2 column3
                    row1 0 1 2
                    row2 3 4 5
                    row3 6 7 8
                    row4 9 10 11


                    Can be transposed using this command:



                    $ transpose -t --fsep " " simple.txt 
                    X row1 row2 row3 row4
                    column1 0 3 6 9
                    column2 1 4 7 10
                    column3 2 5 8 11


                    This command is transpose to transpose (-t) and the field separator to use is a space (--fsep " ").



                    Your example



                    Since your sample data is in a slightly more complex format it needs to be dealt with in 2 phases. First we need to translate it into a format that transpose can deal with.



                    Running this command, will put the data in a more horizontally friendly format:



                    $ sed 's/:/ /; /^$/d' sample.txt 
                    | sort | paste - - - - -
                    title1 A1 title1 B1 title1 C1 title1 D1 title2 A2
                    title2 B2 title2 C2 title2 D2 title3 A3 title3 B3
                    title3 C3 title3 D3 title4 A4 title4 B4 title4 C4
                    title4 D4 title5 A5 title5 B5 title5 C5 title5 D5


                    Now we just need to remove the secondary occurrences of the title1, title2, etc.:



                    $ sed 's/:/ /; /^$/d' sample.txt 
                    | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                    title1 A1 B1 C1 D1 A2
                    title2 B2 C2 D2 A3 B3
                    title3 C3 D3 A4 B4 C4
                    title4 D4 A5 B5 C5 D5


                    It's now in a format that transpose can deal with. The following command will do the entire transposition:



                    $ sed 's/:/ /; /^$/d' sample.txt 
                    | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                    | transpose -t --fsep " "
                    title1 title2 title3 title4
                    A1 B2 C3 D4
                    B1 C2 D3 A5
                    C1 D2 A4 B5
                    D1 A3 B4 C5
                    A2 B3 C4 D5





                    share|improve this answer



























                      8














                      Outside of rolling a custom solution to transpose rows with columns from a command line the only tool I've ever seen that can do this is a tool called ironically transpose.



                      Installation



                      Unfortunately it's not in any repo so you'll need to download and compile it. This is pretty straightforward since it has no additional libraries that it's dependent on. It can be accomplished like so:



                      $ gcc transpose.c -o transpose


                      Usage



                      It can handle straightforward text files with ease. For example:



                      $ cat simple.txt 
                      X column1 column2 column3
                      row1 0 1 2
                      row2 3 4 5
                      row3 6 7 8
                      row4 9 10 11


                      Can be transposed using this command:



                      $ transpose -t --fsep " " simple.txt 
                      X row1 row2 row3 row4
                      column1 0 3 6 9
                      column2 1 4 7 10
                      column3 2 5 8 11


                      This command is transpose to transpose (-t) and the field separator to use is a space (--fsep " ").



                      Your example



                      Since your sample data is in a slightly more complex format it needs to be dealt with in 2 phases. First we need to translate it into a format that transpose can deal with.



                      Running this command, will put the data in a more horizontally friendly format:



                      $ sed 's/:/ /; /^$/d' sample.txt 
                      | sort | paste - - - - -
                      title1 A1 title1 B1 title1 C1 title1 D1 title2 A2
                      title2 B2 title2 C2 title2 D2 title3 A3 title3 B3
                      title3 C3 title3 D3 title4 A4 title4 B4 title4 C4
                      title4 D4 title5 A5 title5 B5 title5 C5 title5 D5


                      Now we just need to remove the secondary occurrences of the title1, title2, etc.:



                      $ sed 's/:/ /; /^$/d' sample.txt 
                      | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                      title1 A1 B1 C1 D1 A2
                      title2 B2 C2 D2 A3 B3
                      title3 C3 D3 A4 B4 C4
                      title4 D4 A5 B5 C5 D5


                      It's now in a format that transpose can deal with. The following command will do the entire transposition:



                      $ sed 's/:/ /; /^$/d' sample.txt 
                      | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                      | transpose -t --fsep " "
                      title1 title2 title3 title4
                      A1 B2 C3 D4
                      B1 C2 D3 A5
                      C1 D2 A4 B5
                      D1 A3 B4 C5
                      A2 B3 C4 D5





                      share|improve this answer

























                        8












                        8








                        8







                        Outside of rolling a custom solution to transpose rows with columns from a command line the only tool I've ever seen that can do this is a tool called ironically transpose.



                        Installation



                        Unfortunately it's not in any repo so you'll need to download and compile it. This is pretty straightforward since it has no additional libraries that it's dependent on. It can be accomplished like so:



                        $ gcc transpose.c -o transpose


                        Usage



                        It can handle straightforward text files with ease. For example:



                        $ cat simple.txt 
                        X column1 column2 column3
                        row1 0 1 2
                        row2 3 4 5
                        row3 6 7 8
                        row4 9 10 11


                        Can be transposed using this command:



                        $ transpose -t --fsep " " simple.txt 
                        X row1 row2 row3 row4
                        column1 0 3 6 9
                        column2 1 4 7 10
                        column3 2 5 8 11


                        This command is transpose to transpose (-t) and the field separator to use is a space (--fsep " ").



                        Your example



                        Since your sample data is in a slightly more complex format it needs to be dealt with in 2 phases. First we need to translate it into a format that transpose can deal with.



                        Running this command, will put the data in a more horizontally friendly format:



                        $ sed 's/:/ /; /^$/d' sample.txt 
                        | sort | paste - - - - -
                        title1 A1 title1 B1 title1 C1 title1 D1 title2 A2
                        title2 B2 title2 C2 title2 D2 title3 A3 title3 B3
                        title3 C3 title3 D3 title4 A4 title4 B4 title4 C4
                        title4 D4 title5 A5 title5 B5 title5 C5 title5 D5


                        Now we just need to remove the secondary occurrences of the title1, title2, etc.:



                        $ sed 's/:/ /; /^$/d' sample.txt 
                        | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                        title1 A1 B1 C1 D1 A2
                        title2 B2 C2 D2 A3 B3
                        title3 C3 D3 A4 B4 C4
                        title4 D4 A5 B5 C5 D5


                        It's now in a format that transpose can deal with. The following command will do the entire transposition:



                        $ sed 's/:/ /; /^$/d' sample.txt 
                        | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                        | transpose -t --fsep " "
                        title1 title2 title3 title4
                        A1 B2 C3 D4
                        B1 C2 D3 A5
                        C1 D2 A4 B5
                        D1 A3 B4 C5
                        A2 B3 C4 D5





                        share|improve this answer













                        Outside of rolling a custom solution to transpose rows with columns from a command line the only tool I've ever seen that can do this is a tool called ironically transpose.



                        Installation



                        Unfortunately it's not in any repo so you'll need to download and compile it. This is pretty straightforward since it has no additional libraries that it's dependent on. It can be accomplished like so:



                        $ gcc transpose.c -o transpose


                        Usage



                        It can handle straightforward text files with ease. For example:



                        $ cat simple.txt 
                        X column1 column2 column3
                        row1 0 1 2
                        row2 3 4 5
                        row3 6 7 8
                        row4 9 10 11


                        Can be transposed using this command:



                        $ transpose -t --fsep " " simple.txt 
                        X row1 row2 row3 row4
                        column1 0 3 6 9
                        column2 1 4 7 10
                        column3 2 5 8 11


                        This command is transpose to transpose (-t) and the field separator to use is a space (--fsep " ").



                        Your example



                        Since your sample data is in a slightly more complex format it needs to be dealt with in 2 phases. First we need to translate it into a format that transpose can deal with.



                        Running this command, will put the data in a more horizontally friendly format:



                        $ sed 's/:/ /; /^$/d' sample.txt 
                        | sort | paste - - - - -
                        title1 A1 title1 B1 title1 C1 title1 D1 title2 A2
                        title2 B2 title2 C2 title2 D2 title3 A3 title3 B3
                        title3 C3 title3 D3 title4 A4 title4 B4 title4 C4
                        title4 D4 title5 A5 title5 B5 title5 C5 title5 D5


                        Now we just need to remove the secondary occurrences of the title1, title2, etc.:



                        $ sed 's/:/ /; /^$/d' sample.txt 
                        | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                        title1 A1 B1 C1 D1 A2
                        title2 B2 C2 D2 A3 B3
                        title3 C3 D3 A4 B4 C4
                        title4 D4 A5 B5 C5 D5


                        It's now in a format that transpose can deal with. The following command will do the entire transposition:



                        $ sed 's/:/ /; /^$/d' sample.txt 
                        | sort | paste - - - - - | sed 's/ttitle[0-9] / /g'
                        | transpose -t --fsep " "
                        title1 title2 title3 title4
                        A1 B2 C3 D4
                        B1 C2 D3 A5
                        C1 D2 A4 B5
                        D1 A3 B4 C5
                        A2 B3 C4 D5






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Aug 26 '13 at 3:48









                        slmslm

                        249k66519679




                        249k66519679





















                            7














                            Here's a quick way to put the file into the format you want:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/title[0-9]://g' | paste - - - -
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            If you want the column headers:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't'; 
                            echo "";
                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -
                            title1 title2 title3 title4
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            How the 2nd command works



                            printing the banner

                            grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't';


                            putting a return after the banner in

                            echo


                            printing the rows of data

                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -





                            share|improve this answer

























                            • paste command simply made my job done. thanks for the answer...

                              – S.K. Venkat
                              Jul 22 '17 at 12:21















                            7














                            Here's a quick way to put the file into the format you want:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/title[0-9]://g' | paste - - - -
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            If you want the column headers:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't'; 
                            echo "";
                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -
                            title1 title2 title3 title4
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            How the 2nd command works



                            printing the banner

                            grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't';


                            putting a return after the banner in

                            echo


                            printing the rows of data

                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -





                            share|improve this answer

























                            • paste command simply made my job done. thanks for the answer...

                              – S.K. Venkat
                              Jul 22 '17 at 12:21













                            7












                            7








                            7







                            Here's a quick way to put the file into the format you want:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/title[0-9]://g' | paste - - - -
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            If you want the column headers:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't'; 
                            echo "";
                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -
                            title1 title2 title3 title4
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            How the 2nd command works



                            printing the banner

                            grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't';


                            putting a return after the banner in

                            echo


                            printing the rows of data

                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -





                            share|improve this answer















                            Here's a quick way to put the file into the format you want:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/title[0-9]://g' | paste - - - -
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            If you want the column headers:



                            $ grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't'; 
                            echo "";
                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -
                            title1 title2 title3 title4
                            A1 A2 A3 A4
                            B1 B2 B3 B4
                            C1 C2 C3 C4
                            D1 D2 D3 D4


                            How the 2nd command works



                            printing the banner

                            grep -Ev "^$|title5" sample.txt | sed 's/:.*//' | sort -u | tr 'n' 't';


                            putting a return after the banner in

                            echo


                            printing the rows of data

                            grep -Ev "^$|title5" a | sed 's/title[0-9]://g' | paste - - - -






                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Jun 17 '13 at 10:21

























                            answered Jun 17 '13 at 3:14









                            slmslm

                            249k66519679




                            249k66519679












                            • paste command simply made my job done. thanks for the answer...

                              – S.K. Venkat
                              Jul 22 '17 at 12:21

















                            • paste command simply made my job done. thanks for the answer...

                              – S.K. Venkat
                              Jul 22 '17 at 12:21
















                            paste command simply made my job done. thanks for the answer...

                            – S.K. Venkat
                            Jul 22 '17 at 12:21





                            paste command simply made my job done. thanks for the answer...

                            – S.K. Venkat
                            Jul 22 '17 at 12:21











                            3














                            There's probably a more succinct way of formulating this but this seems to accomplish the general effect:



                            [jadavis84@localhost ~]$ sed 's/^title[2-9]://g' file.txt | tr 'n' 't' | sed 's/title1:/n/g' ; echo

                            A1 A2 A3 A4 A5
                            B1 B2 B3 B4 B5
                            C1 C2 C3 C4 C5
                            D1 D2 D3 D4 D5
                            [jadavis84@localhost ~]$


                            Multiple sed invocations doesn't feel right (and I'm pretty sure sed can do the new line translation as well) so it probably isn't the most straight forward way to do it. Also, this strips the would-be headers, but you can generate those manually once you have the rows/fields formatted properly.



                            A better answer would probably distill that effect down to just using sed or awk to do this so that you only have one thing going on at a time. But I'm tired so this is what I was able to put together.






                            share|improve this answer























                            • Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

                              – slm
                              Jun 17 '13 at 3:23











                            • Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

                              – Bratchley
                              Jun 17 '13 at 11:13















                            3














                            There's probably a more succinct way of formulating this but this seems to accomplish the general effect:



                            [jadavis84@localhost ~]$ sed 's/^title[2-9]://g' file.txt | tr 'n' 't' | sed 's/title1:/n/g' ; echo

                            A1 A2 A3 A4 A5
                            B1 B2 B3 B4 B5
                            C1 C2 C3 C4 C5
                            D1 D2 D3 D4 D5
                            [jadavis84@localhost ~]$


                            Multiple sed invocations doesn't feel right (and I'm pretty sure sed can do the new line translation as well) so it probably isn't the most straight forward way to do it. Also, this strips the would-be headers, but you can generate those manually once you have the rows/fields formatted properly.



                            A better answer would probably distill that effect down to just using sed or awk to do this so that you only have one thing going on at a time. But I'm tired so this is what I was able to put together.






                            share|improve this answer























                            • Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

                              – slm
                              Jun 17 '13 at 3:23











                            • Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

                              – Bratchley
                              Jun 17 '13 at 11:13













                            3












                            3








                            3







                            There's probably a more succinct way of formulating this but this seems to accomplish the general effect:



                            [jadavis84@localhost ~]$ sed 's/^title[2-9]://g' file.txt | tr 'n' 't' | sed 's/title1:/n/g' ; echo

                            A1 A2 A3 A4 A5
                            B1 B2 B3 B4 B5
                            C1 C2 C3 C4 C5
                            D1 D2 D3 D4 D5
                            [jadavis84@localhost ~]$


                            Multiple sed invocations doesn't feel right (and I'm pretty sure sed can do the new line translation as well) so it probably isn't the most straight forward way to do it. Also, this strips the would-be headers, but you can generate those manually once you have the rows/fields formatted properly.



                            A better answer would probably distill that effect down to just using sed or awk to do this so that you only have one thing going on at a time. But I'm tired so this is what I was able to put together.






                            share|improve this answer













                            There's probably a more succinct way of formulating this but this seems to accomplish the general effect:



                            [jadavis84@localhost ~]$ sed 's/^title[2-9]://g' file.txt | tr 'n' 't' | sed 's/title1:/n/g' ; echo

                            A1 A2 A3 A4 A5
                            B1 B2 B3 B4 B5
                            C1 C2 C3 C4 C5
                            D1 D2 D3 D4 D5
                            [jadavis84@localhost ~]$


                            Multiple sed invocations doesn't feel right (and I'm pretty sure sed can do the new line translation as well) so it probably isn't the most straight forward way to do it. Also, this strips the would-be headers, but you can generate those manually once you have the rows/fields formatted properly.



                            A better answer would probably distill that effect down to just using sed or awk to do this so that you only have one thing going on at a time. But I'm tired so this is what I was able to put together.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jun 17 '13 at 2:34









                            BratchleyBratchley

                            12k74388




                            12k74388












                            • Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

                              – slm
                              Jun 17 '13 at 3:23











                            • Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

                              – Bratchley
                              Jun 17 '13 at 11:13

















                            • Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

                              – slm
                              Jun 17 '13 at 3:23











                            • Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

                              – Bratchley
                              Jun 17 '13 at 11:13
















                            Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

                            – slm
                            Jun 17 '13 at 3:23





                            Joel - I made the same mistake and just noticed it, he doesn't want the title5 column in the output.

                            – slm
                            Jun 17 '13 at 3:23













                            Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

                            – Bratchley
                            Jun 17 '13 at 11:13





                            Ah, well running through awk at the last should fix that. But it looks like Sukminder's posted a complete solution.

                            – Bratchley
                            Jun 17 '13 at 11:13











                            3














                            GNU datamash utility



                            apt install datamash 

                            datamash transpose < yourfile


                            Taken from this site, https://www.gnu.org/software/datamash/ and http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods






                            share|improve this answer



























                              3














                              GNU datamash utility



                              apt install datamash 

                              datamash transpose < yourfile


                              Taken from this site, https://www.gnu.org/software/datamash/ and http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods






                              share|improve this answer

























                                3












                                3








                                3







                                GNU datamash utility



                                apt install datamash 

                                datamash transpose < yourfile


                                Taken from this site, https://www.gnu.org/software/datamash/ and http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods






                                share|improve this answer













                                GNU datamash utility



                                apt install datamash 

                                datamash transpose < yourfile


                                Taken from this site, https://www.gnu.org/software/datamash/ and http://www.thelinuxrain.com/articles/transposing-rows-and-columns-3-methods







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Apr 7 '17 at 8:59









                                nelaaronelaaro

                                5602614




                                5602614





















                                    1














                                    paste is probably your best bet. You can extract the relevant bits with cut, grep and awk like this:



                                    (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile)


                                    If the 5th column should be eliminated, append awk 'NR%5' like this:



                                    (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5'


                                    Now columnate with paste:



                                    (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5' | paste - - - -


                                    Output:



                                    title1 title2 title3 title4
                                    A1 A2 A3 A4
                                    B1 B2 B3 B4
                                    C1 C2 C3 C4
                                    D1 D2 D3 D4





                                    share|improve this answer



























                                      1














                                      paste is probably your best bet. You can extract the relevant bits with cut, grep and awk like this:



                                      (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile)


                                      If the 5th column should be eliminated, append awk 'NR%5' like this:



                                      (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5'


                                      Now columnate with paste:



                                      (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5' | paste - - - -


                                      Output:



                                      title1 title2 title3 title4
                                      A1 A2 A3 A4
                                      B1 B2 B3 B4
                                      C1 C2 C3 C4
                                      D1 D2 D3 D4





                                      share|improve this answer

























                                        1












                                        1








                                        1







                                        paste is probably your best bet. You can extract the relevant bits with cut, grep and awk like this:



                                        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile)


                                        If the 5th column should be eliminated, append awk 'NR%5' like this:



                                        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5'


                                        Now columnate with paste:



                                        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5' | paste - - - -


                                        Output:



                                        title1 title2 title3 title4
                                        A1 A2 A3 A4
                                        B1 B2 B3 B4
                                        C1 C2 C3 C4
                                        D1 D2 D3 D4





                                        share|improve this answer













                                        paste is probably your best bet. You can extract the relevant bits with cut, grep and awk like this:



                                        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile)


                                        If the 5th column should be eliminated, append awk 'NR%5' like this:



                                        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5'


                                        Now columnate with paste:



                                        (awk 'NR==1' RS= infile | cut -d: -f1; cut -sd: -f2 infile) | awk 'NR%5' | paste - - - -


                                        Output:



                                        title1 title2 title3 title4
                                        A1 A2 A3 A4
                                        B1 B2 B3 B4
                                        C1 C2 C3 C4
                                        D1 D2 D3 D4






                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Feb 18 '15 at 14:27









                                        ThorThor

                                        11.7k13459




                                        11.7k13459





















                                            0














                                            For just the transpose part, I had a similar problem recently and used:



                                            awk -v fmt='t%4s' ' for(i=1;i<=NF;i++) a[i]=a[i] sprintf(fmt, $i); END for (i in a) print a[i]; '


                                            Adjust the fmt as needed. For each input line, it concatenates each fields onto an array element. Note that awk string concatenation is implicit: it happens when you write two things without any operator.



                                            Sample I/O:



                                            i mark accep igna utaal bta
                                            -22 -10 -10 -20 -10 -10
                                            -21 -10 -10 -20 -10 -10
                                            -20 -10 -10 -20 -10 -10
                                            -19 -10 0 -10 -10 -10
                                            -18 0 0 -10 0 0
                                            -12 0 0 -10 0 0
                                            -11 0 0 -10 0 0
                                            -10 0 0 -10 0 0


                                            output:



                                             i -22 -21 -20 -19 -18 -12 -11 -10
                                            mark -10 -10 -10 -10 0 0 0 0
                                            accep -10 -10 -10 0 0 0 0 0
                                            igna -20 -20 -20 -10 -10 -10 -10 -10
                                            utaal -10 -10 -10 -10 0 0 0 0
                                            bta -10 -10 -10 -10 0 0 0 0





                                            share|improve this answer





























                                              0














                                              For just the transpose part, I had a similar problem recently and used:



                                              awk -v fmt='t%4s' ' for(i=1;i<=NF;i++) a[i]=a[i] sprintf(fmt, $i); END for (i in a) print a[i]; '


                                              Adjust the fmt as needed. For each input line, it concatenates each fields onto an array element. Note that awk string concatenation is implicit: it happens when you write two things without any operator.



                                              Sample I/O:



                                              i mark accep igna utaal bta
                                              -22 -10 -10 -20 -10 -10
                                              -21 -10 -10 -20 -10 -10
                                              -20 -10 -10 -20 -10 -10
                                              -19 -10 0 -10 -10 -10
                                              -18 0 0 -10 0 0
                                              -12 0 0 -10 0 0
                                              -11 0 0 -10 0 0
                                              -10 0 0 -10 0 0


                                              output:



                                               i -22 -21 -20 -19 -18 -12 -11 -10
                                              mark -10 -10 -10 -10 0 0 0 0
                                              accep -10 -10 -10 0 0 0 0 0
                                              igna -20 -20 -20 -10 -10 -10 -10 -10
                                              utaal -10 -10 -10 -10 0 0 0 0
                                              bta -10 -10 -10 -10 0 0 0 0





                                              share|improve this answer



























                                                0












                                                0








                                                0







                                                For just the transpose part, I had a similar problem recently and used:



                                                awk -v fmt='t%4s' ' for(i=1;i<=NF;i++) a[i]=a[i] sprintf(fmt, $i); END for (i in a) print a[i]; '


                                                Adjust the fmt as needed. For each input line, it concatenates each fields onto an array element. Note that awk string concatenation is implicit: it happens when you write two things without any operator.



                                                Sample I/O:



                                                i mark accep igna utaal bta
                                                -22 -10 -10 -20 -10 -10
                                                -21 -10 -10 -20 -10 -10
                                                -20 -10 -10 -20 -10 -10
                                                -19 -10 0 -10 -10 -10
                                                -18 0 0 -10 0 0
                                                -12 0 0 -10 0 0
                                                -11 0 0 -10 0 0
                                                -10 0 0 -10 0 0


                                                output:



                                                 i -22 -21 -20 -19 -18 -12 -11 -10
                                                mark -10 -10 -10 -10 0 0 0 0
                                                accep -10 -10 -10 0 0 0 0 0
                                                igna -20 -20 -20 -10 -10 -10 -10 -10
                                                utaal -10 -10 -10 -10 0 0 0 0
                                                bta -10 -10 -10 -10 0 0 0 0





                                                share|improve this answer















                                                For just the transpose part, I had a similar problem recently and used:



                                                awk -v fmt='t%4s' ' for(i=1;i<=NF;i++) a[i]=a[i] sprintf(fmt, $i); END for (i in a) print a[i]; '


                                                Adjust the fmt as needed. For each input line, it concatenates each fields onto an array element. Note that awk string concatenation is implicit: it happens when you write two things without any operator.



                                                Sample I/O:



                                                i mark accep igna utaal bta
                                                -22 -10 -10 -20 -10 -10
                                                -21 -10 -10 -20 -10 -10
                                                -20 -10 -10 -20 -10 -10
                                                -19 -10 0 -10 -10 -10
                                                -18 0 0 -10 0 0
                                                -12 0 0 -10 0 0
                                                -11 0 0 -10 0 0
                                                -10 0 0 -10 0 0


                                                output:



                                                 i -22 -21 -20 -19 -18 -12 -11 -10
                                                mark -10 -10 -10 -10 0 0 0 0
                                                accep -10 -10 -10 0 0 0 0 0
                                                igna -20 -20 -20 -10 -10 -10 -10 -10
                                                utaal -10 -10 -10 -10 0 0 0 0
                                                bta -10 -10 -10 -10 0 0 0 0






                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Mar 3 '16 at 7:55

























                                                answered Mar 3 '16 at 7:02









                                                Peter CordesPeter Cordes

                                                4,1731332




                                                4,1731332





















                                                    -1














                                                    The simplest thing you can do is to use cut to cut the fields and then use tr if you're transposing rows to columns by replacing the newline character with a tab character: http://www.gnu.org/software/coreutils/manual/coreutils.html#tr-invocation



                                                    cat file.txt | cut -d':' | tr 'n' 't'





                                                    share|improve this answer























                                                    • Without a list of fields, cut returns an error.

                                                      – agc
                                                      Jul 13 '16 at 13:28















                                                    -1














                                                    The simplest thing you can do is to use cut to cut the fields and then use tr if you're transposing rows to columns by replacing the newline character with a tab character: http://www.gnu.org/software/coreutils/manual/coreutils.html#tr-invocation



                                                    cat file.txt | cut -d':' | tr 'n' 't'





                                                    share|improve this answer























                                                    • Without a list of fields, cut returns an error.

                                                      – agc
                                                      Jul 13 '16 at 13:28













                                                    -1












                                                    -1








                                                    -1







                                                    The simplest thing you can do is to use cut to cut the fields and then use tr if you're transposing rows to columns by replacing the newline character with a tab character: http://www.gnu.org/software/coreutils/manual/coreutils.html#tr-invocation



                                                    cat file.txt | cut -d':' | tr 'n' 't'





                                                    share|improve this answer













                                                    The simplest thing you can do is to use cut to cut the fields and then use tr if you're transposing rows to columns by replacing the newline character with a tab character: http://www.gnu.org/software/coreutils/manual/coreutils.html#tr-invocation



                                                    cat file.txt | cut -d':' | tr 'n' 't'






                                                    share|improve this answer












                                                    share|improve this answer



                                                    share|improve this answer










                                                    answered May 30 '16 at 16:44









                                                    Rudolf OlahRudolf Olah

                                                    11119




                                                    11119












                                                    • Without a list of fields, cut returns an error.

                                                      – agc
                                                      Jul 13 '16 at 13:28

















                                                    • Without a list of fields, cut returns an error.

                                                      – agc
                                                      Jul 13 '16 at 13:28
















                                                    Without a list of fields, cut returns an error.

                                                    – agc
                                                    Jul 13 '16 at 13:28





                                                    Without a list of fields, cut returns an error.

                                                    – agc
                                                    Jul 13 '16 at 13:28

















                                                    draft saved

                                                    draft discarded
















































                                                    Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid


                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.

                                                    To learn more, see our tips on writing great answers.




                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function ()
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f79642%2ftransposing-rows-and-columns%23new-answer', 'question_page');

                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown






                                                    Popular posts from this blog

                                                    How to check contact read email or not when send email to Individual?

                                                    Bahrain

                                                    Postfix configuration issue with fips on centos 7; mailgun relay