Sie können Anführungszeichen mit sed hinzufügen und dann Zeilen mit Einfügen zusammenführen , so:
sed 's/^\|$/"/g'|paste -sd, -
Wenn Sie ein auf GNU Coreutils basierendes System (z. B. Linux) ausführen, können Sie den abschließenden '-'
weglassen .
Wenn Ihre Eingabedaten Zeilenenden im DOS-Stil haben (wie von @phk vorgeschlagen), können Sie den Befehl wie folgt ändern:
sed 's/\r//;s/^\|$/"/g'|paste -sd, -
Mit
awk
:awk 'BEGIN { ORS="" } { print p"'"'"'"$0"'"'"'"; p=", " } END { print "\n" }' /path/to/list
Alternative mit weniger Shell-Escape und daher besser lesbar:awk 'BEGIN { ORS="" } { print p"\047"$0"\047"; p=", " } END { print "\n" }' /path/to/list
Ausgabe:'d3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Erläuterung:
Die awk
Das Skript selbst ohne alle Escapezeichen ist BEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Nach dem Drucken des ersten Eintrags wird die Variable p
gesetzt ist (vorher ist es wie ein leerer String). Mit dieser Variable p
jedem Eintrag (oder in awk
-speak:aufzeichnen ) wird vorangestellt und zusätzlich in einfache Anführungszeichen gesetzt. Die awk
Datensatz-Trennvariable ORS
ausgeben wird nicht benötigt (da das Präfix dies für Sie erledigt), daher wird es bei BEGIN
auf leer gesetzt ing. Oh, und wir könnten unsere Datei zu END
mit Zeilenumbruch (z. B. damit es mit weiteren Textverarbeitungswerkzeugen funktioniert); sollte dies nicht benötigt werden, den Teil mit END
und alles danach (innerhalb der einfachen Anführungszeichen) kann entfernt werden.
Wenn Sie Zeilenenden im Windows/DOS-Stil haben (\r\n
), müssen Sie sie in den UNIX-Stil konvertieren (\n
) Erste. Dazu können Sie tr -d '\015'
eingeben am Anfang Ihrer Pipeline:
tr -d '\015' < /path/to/input.list | awk […] > /path/to/output
(Angenommen, Sie haben keine Verwendung für \r
s in Ihrer Datei. Sehr sichere Annahme hier.)
Alternativ führen Sie einfach dos2unix /path/to/input.list
aus einmal, um die Datei direkt zu konvertieren.
Wie die verknüpfte Antwort von @don_crissti zeigt, grenzt die Einfügeoption an unglaublich schnell - das Piping des Linux-Kernels ist effizienter, als ich geglaubt hätte, wenn ich es nicht gerade ausprobiert hätte. Bemerkenswerterweise, wenn Sie mit einem einzelnen Komma zufrieden sein können, das Ihre Listenelemente trennt, anstatt mit einem Komma + Leerzeichen, einer Pipeline zum Einfügen
(paste -d\' /dev/null - /dev/null | paste -sd, -) <input
ist schneller als selbst ein vernünftiger flex
Programm(!)
%option 8bit main fast
%%
.* { printf("'%s'",yytext); }
\n/(.|\n) { printf(", "); }
Aber wenn nur eine anständige Leistung akzeptabel ist (und wenn Sie keinen Stresstest durchführen, können Sie keine Unterschiede in konstanten Faktoren messen, sie sind alle sofort verfügbar) und Sie sowohl Flexibilität bei Ihren Separatoren als auch eine vernünftige wünschen -liner-y-ness,
sed "s/.*/'&'/;H;1h;"'$!d;x;s/\n/, /g'
ist deine Eintrittskarte. Ja, es sieht nach Leitungsrauschen aus, aber die H;1h;$!d;x
idiom ist der richtige Weg, alles zu schlürfen, sobald man erkennt, dass das Ganze tatsächlich leicht lesbar wird, ist es s/.*/'&'/
gefolgt von einem Slurp und einem s/\n/, /g
.
Bearbeiten:An der Grenze zum Absurden, es ist ziemlich einfach, Flex dazu zu bringen, alles andere hohl zu schlagen, sagen Sie einfach stdio, dass Sie die eingebaute Multithread/Signalhandler-Synchronisierung nicht benötigen:
%option 8bit main fast
%%
.+ { putchar_unlocked('\'');
fwrite_unlocked(yytext,yyleng,1,stdout);
putchar_unlocked('\''); }
\n/(.|\n) { fwrite_unlocked(", ",2,1,stdout); }
und unter Stress ist das 2-3x schneller als die Pastenpipelines, die selbst mindestens 5x schneller sind als alles andere.