1

I have a .csv file that is tab delimited and I need to move the header row information to a "new" column at the beginning and a specified numbers of rows down. I would like to use standard tools that I currently use such as sed or awk but if another tool/method is more appropriate I would welcome the suggestion. The header changes per file, that's why I need to copy it instead of just placing the string "CAT" in the appropriate row and column.

                            CAT
    DOG     DOG     DOG     DOG     DOG     DOG     DOG
    DOG     DOG     DOG     DOG     DOG     DOG     DOG
    DOG     DOG     DOG     DOG     DOG     DOG     DOG
    DOG     DOG     DOG     DOG     DOG     DOG     DOG

Would become:

                            CAT
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
    CAT     DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
1

paste can also make it:

edited

This prints the first line again. Taking advantage of the lack of quotes, the trailing spaces are not showing:

$ paste -d"\t" <(printf "\n\n\n%s" $(head -1 file)) file
                                    CAT
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
CAT         DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG

original

$ -d"\t" <(printf "\n\n\nCAT") file
                                    CAT
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
CAT         DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
  • 1
    After trying a couple of the answers/suggestions, I settled on this one because it meets my immediate needs and I understand it's mechanics. Thanks. :-) – user72055 Jun 10 '14 at 17:54
1

The following sed command works for me:

sed '1!s/^/\t/;4s/^/CAT/' 

Interpretation:

On the lines other than number 1, replace the beginning of the line with a tab. On the fourth line, replace the beginning of the line with the CAT string.

  • I like this method, but unfortunately the header "CAT" changes per report that I am modifying and I would like to modify them all at once. So I'm looking for something that will move/copy "CAT" to the appropriate column/row. – user72055 Jun 10 '14 at 15:00
1

You could use sed as follows I think:

  1. save the first line into the hold space
  2. prepend an extra tab (column) from line #2 onward (this preserves the original column alignment of the header)
  3. at a specified following line (I used line #4 in the example below), swap the hold back into pattern space, strip whitespace from it, and prepend it to the line

$ sed -e '1h' -e '2,$s/^/\t/' -e '4{x;s/[[:space:]]//g;G;s/\n//}' file
                                CAT
                DOG     DOG     DOG     DOG     DOG     DOG     DOG
                DOG     DOG     DOG     DOG     DOG     DOG     DOG
    CAT         DOG     DOG     DOG     DOG     DOG     DOG     DOG
                DOG     DOG     DOG     DOG     DOG     DOG     DOG

  • This is good but I don't think you want to strip spaces from the header text if tab is the delimiter. Better would be just to strip tabs or to only keep the first non-blank field as I did with awk. – Graeme Jun 10 '14 at 17:02
0

You could try this awk command also.

$ awk 'NR==1{var=$1} {sub (/^     /,"            ");} NR==4{ sub (/^ +/,""); $0="    "var"     "$0}1' file
                                    CAT                        
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG
    CAT     DOG     DOG     DOG     DOG     DOG     DOG     DOG
            DOG     DOG     DOG     DOG     DOG     DOG     DOG

It fetches the string on the first row and then append the same string at the beginning of line 4.

0

Using awk:

awk -v line=4 -F '^\t*|\t+' '
  NR==1 { OFS="\t"; ins=$2 }
  NR!=line { print "","",$0 }
  NR==line { print "",ins,$0 }' file

This will use the first non-blank field of the header line as the text to insert, so it can have any text apart from a tab or newline. The field separator is set up so that this is always read as the second field in awk.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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