5

Here is the weak attempt at a paste command trying to include a newline:

    paste -d -s tmp1 tmp2 \n tmp3 \n tmp4 tmp5 tmp6 > tmp7

Basically I have several lines in each tmp and I want the output to read

First(tmp1) Last(tmp2)
Address(tmp3)
City(tmp4) State(tmp5) Zip(tmp6)

Am I way off base with using a newline in the paste command?

Here is my finished product: THANK YOU FOR THE HELP!

    cp phbook phbookh2p5

    sed 's/\t/,/g' phbookh2p5 > tmp
    sort -k2 -t ',' -d tmp > tmp0
    cut -d',' -f1,2 tmp0 > tmp1
    cut -d',' -f3 tmp0 > tmp2
    cut -d',' -f4,5,6 tmp0 > tmp3
    echo "" > tmp4

    paste -d '\n' tmp1 tmp2 tmp3 tmp4 > tmp7

    sed 's/\t/ /g' tmp7 > phbookh2p5

    cat phbookh2p5

    rm tmp*; rm phbookh2p5
7

Try this solution with two extra temporary files:

paste tmp1 tmp2 > tmp12
paste tmp4 tmp5 tmp6 > tmp456
paste -d "\n" tmp12 tmp3 tmp456 > tmp7

This solution was based on the assumption that the -d option selects the delimiter globally for all input files so it either be a blank or a newline. In a way this is true since later occurences of -d overwrite previous ones. However, as @DigitalTrauma pointed out we can supply more than one delimiter which will be used sequentially. So @DigitalTrauma's solution is more elegant than mine since it completely avoids additional temporary files.

One niche application for my solution would be the case in which one or delimiters with more than one character each have to be used. This should not be possible with just using the -d option.

  • 1
    +1 Thanks for letting me know @Marcus. It is worth knowing that we could set the delimiter globally. – Ramesh Oct 15 '14 at 21:28
  • @Ramesh Well, maybe there are different flavors of paste around. The one I use (paste (GNU coreutils) 8.21) only heeds the last instance of -d on the command line. – Marcus Rickert Oct 15 '14 at 21:32
  • @DigitalTrauma: Thanks for pointing this out. I will update my answer. +1 for yours. – Marcus Rickert Oct 16 '14 at 16:46
4

I think this part of the paste man page is what you want:

   -d, --delimiters=LIST
          reuse characters from LIST instead of TABs

So this one-liner should work for your case:

paste -d" \n\n  " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 > tmp7

Works as expected with @DopeGhoti's sample data:

$ grep . tmp*
tmp1:Bill
tmp1:Bob
tmp2:Kerman
tmp2:Germin
tmp3:123 Main St.
tmp3:321 Sesame St.
tmp4:Kerbopalis
tmp4:Kerbington
tmp5:Kerbskatchewan
tmp5:Kermont
tmp6:12345
tmp6:31416
$ paste -d" \n\n  " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6
Bill Kerman
123 Main St.
Kerbopalis Kerbskatchewan 12345
Bob Germin
321 Sesame St.
Kerbington Kermont 31416
$ 

I've tested this successfully with paste from GNU Coreutils 5.97 and 8.21 and BSD (OS X). Not sure what other versions of paste are out there in the wild.

1

This command should work.

 paste -s tmp1 tmp2 -d '\n' tmp3 -d '\n' tmp4 tmp5 tmp6 > tmp7
  • According to what I tried -d sets the delimiter globally. – Marcus Rickert Oct 15 '14 at 21:22
  • @MarcusRickert, do you mean if you use paste -s -d '\n' file1 file2 file3 > file4, it worked? I tried and it did seem to work. – Ramesh Oct 15 '14 at 21:26
  • It def got me close but for whatever reason I did an update and it all worked for me both ways. I found a happy medium and have the output I needed. Thanks guys! – user3347022 Oct 15 '14 at 21:26
0

You might get by combining paste and awk:

paste -d'|' tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 | awk 'BEGIN { FS = "|" }; {print $1, $2 "\n" $3 "\n" $4, $5, $6}' > tmp7

Example output from some test data I threw together for the tmp files:

Bill Kerman
123 Main St.
Kerbopalis Kerbskatchewan 12345
Bob Germin
321 Sesame St.
Kerbington Kermont 31416
-1
sort -dk2,2 phpbook |
sed "s/\t/\n/3;s//\n/2;s// /g"

As I understand it you have a file called phpbook that consists of lines of phone book entries that look like this:

{first}\t{last}\t{address}\t{city}\t{state}\t{zip}

You want to sort these on {last}, add newlines following {last} and {address} for each entry, translate \tabs to <spaces> and then print the results to stdout. If that is not the case then I can't make out what else your command would do - but I can be pretty dense sometimes.

You should note that sort delimits by <TAB> characters by default so:

sed 's/\t/,/g' | sort ... -t ,

...probably isn't worth doing.

Thinking about is some more and I suppose it's pretty likely that your delimiters are mixed and the inital sed is intended to normalize them. That makes sense. Maybe like:

1,2\t3\t4,5,6

...or something. In that case an initial translation of some kind is necessary. So maybe...

tr , \\t <phbook | sort ... | sed ...

would work a little bettet. Also...

sort ... -k 2

...might be problematic in edge cases because when you use it you do not sort on only the second field, but rather from the second field to the end of line. In general when people do that they really want -k2,2 which confines the data sort considers to only the second field.

It might also be worthwhile to add a secondary key like:

...sort -dk2,2 -k1,1

...which would sort primarily on last names and secondarily on first names. In that way Zed Smith would follow Alpha Smith every time.

Anyway, on the off-chance I'm right, the sort | sed pipeline above should do the whole thing. I'm assuming your sed understands the \escapes I used, but if it doesn't then you can try replacing the quoted sed script with:

s/<literal TAB>/\
/3;s//\
/2;s// /g

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.