Hier ist der schwache Versuch eines Einfügebefehls, der eine neue Zeile einfügt:
paste -d -s tmp1 tmp2 \n tmp3 \n tmp4 tmp5 tmp6 > tmp7
Im Grunde habe ich mehrere Zeilen in jedem temporären Dokument und ich möchte, dass die Ausgabe lautet
First(tmp1) Last(tmp2)
Address(tmp3)
City(tmp4) State(tmp5) Zip(tmp6)
Bin ich völlig auf dem Holzweg, wenn ich im Einfügebefehl eine neue Zeile verwende?
Hier ist mein fertiges Produkt: DANKE FÜR DIE HILFE!
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
Antwort1
Versuchen Sie diese Lösung mit zwei zusätzlichen temporären Dateien:
paste tmp1 tmp2 > tmp12
paste tmp4 tmp5 tmp6 > tmp456
paste -d "\n" tmp12 tmp3 tmp456 > tmp7
Diese Lösung basierte auf der Annahme, dass die -d
Option das Trennzeichen auswähltglobalfür alle Eingabedateien, also ist es entweder leerodereine neue Zeile. In gewisser Weise stimmt das, da spätere Vorkommen -d
vorherige überschreiben. Wie @DigitalTrauma jedoch anmerkte, können wir mehr als ein Trennzeichen angeben, das nacheinander verwendet wird. Daher ist die Lösung von @DigitalTrauma eleganter als meine, da sie zusätzliche temporäre Dateien vollständig vermeidet.
Eine Nischenanwendung für meine Lösung wäre der Fall, in dem ein oder mehrere Trennzeichen mitjeweils mehr als ein Zeichenverwendet werden. Dies sollte allein durch die Verwendung der -d
Option nicht möglich sein.
Antwort2
Ich denke, dieser Teil der paste
Manpage ist das, was Sie wollen:
-d, --delimiters=LIST reuse characters from LIST instead of TABs
Dieser Einzeiler sollte also in Ihrem Fall funktionieren:
paste -d" \n\n " tmp1 tmp2 tmp3 tmp4 tmp5 tmp6 > tmp7
Funktioniert wie erwartet mit den Beispieldaten von @DopeGhoti:
$ 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
$
Ich habe dies erfolgreich mit paste
GNU Coreutils 5.97 und 8.21 und BSD (OS X) getestet. Ich bin mir nicht sicher, welche anderen Versionen von Paste es noch gibt.
Antwort3
Dieser Befehl sollte funktionieren.
paste -s tmp1 tmp2 -d '\n' tmp3 -d '\n' tmp4 tmp5 tmp6 > tmp7
Antwort4
sort -dk2,2 phpbook |
sed "s/\t/\n/3;s//\n/2;s// /g"
So wie ich es verstehe, haben Sie eine Datei mit dem Namen phpbook
, die aus Zeilen mit Telefonbucheinträgen besteht, die folgendermaßen aussehen:
{first}\t{last}\t{address}\t{city}\t{state}\t{zip}
Sie möchten diese nach sortieren {last}
, danach Zeilenumbrüche hinzufügen {last}
und für jeden Eintrag abs nach {address}
übersetzen und dann die Ergebnisse nach drucken . Wenn das nicht der Fall ist, kann ich mir nicht vorstellen, was Ihr Befehl sonst tun würde – aber ich kann manchmal ziemlich schwer von Begriff sein. \t
<spaces>
stdout
Beachten Sie, dass die Trennzeichen standardmäßig folgendermaßen sort
aussehen :<TAB>
sed 's/\t/,/g' | sort ... -t ,
... lohnt sich wahrscheinlich nicht.
Wenn ich noch darüber nachdenke, ist es ziemlich wahrscheinlich, dass Ihre Trennzeichen gemischt sind und der Anfangssatz dazu sed
gedacht ist, sie zu normalisieren. Das macht Sinn. Vielleicht so:
1,2\t3\t4,5,6
...oder so. In diesem Fall ist eine anfängliche Übersetzung irgendeiner Art erforderlich. Also vielleicht...
tr , \\t <phbook | sort ... | sed ...
würde etwas besser funktionieren. Also ...
sort ... -k 2
...könntekann in Randfällen problematisch sein, denn wenn Sie es verwenden sort
,nurdas zweite Feld, sondern vom zweiten Feld bis zum Ende der Zeile. Im Allgemeinen, wenn die Leute das tun, wollen sie wirklich, -k2,2
was die Daten beschränkt sort
betrachtet aufnurdas zweite Feld.
Es kann auch sinnvoll sein, einen Sekundärschlüssel hinzuzufügen, wie:
...sort -dk2,2 -k1,1
...was würdesort
in erster Linieauf Nachnamen undsekundärauf Vornamen. Auf diese WeiseZed Smithwürde folgenAlpha Smithjedes Mal.
Wie auch immer, für den unwahrscheinlichen Fall, dass ich Recht habe, sort | sed
sollte die obige Pipeline das Ganze erledigen. Ich gehe davon aus, dass Sie sed
die von mir verwendeten Scapes verstehen \e
, aber wenn nicht, können Sie versuchen, das zitierte sed
Skript durch Folgendes zu ersetzen:
s/<literal TAB>/\
/3;s//\
/2;s// /g