Puoi aggiungere virgolette con sed e poi unisci le righe con incolla , così:
sed 's/^\|$/"/g'|paste -sd, -
Se stai eseguendo un sistema basato su coreutils GNU (ad esempio Linux), puoi omettere il '-'
finale .
Se i dati immessi hanno terminazioni di riga in stile DOS (come suggerito da @phk), puoi modificare il comando come segue:
sed 's/\r//;s/^\|$/"/g'|paste -sd, -
Usando
awk
:awk 'BEGIN { ORS="" } { print p"'"'"'"$0"'"'"'"; p=", " } END { print "\n" }' /path/to/list
Alternativa con meno shell di escape e quindi più leggibile:awk 'BEGIN { ORS="" } { print p"\047"$0"\047"; p=", " } END { print "\n" }' /path/to/list
Uscita:'d3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Spiegazione:
Il awk
lo script stesso senza tutti gli escape è BEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Dopo aver stampato la prima voce la variabile p
è impostato (prima è come una stringa vuota). Con questa variabile p
ogni voce (o in awk
-speak:registra ) è preceduto e inoltre stampato con virgolette singole attorno ad esso. Il awk
output variabile separatore di record ORS
non è necessario (poiché il prefisso lo sta facendo per te) quindi è impostato per essere vuoto al BEGIN
ing. Oh, e potremmo portare il nostro file a END
con una nuova riga (ad esempio, quindi funziona con altri strumenti di elaborazione del testo); se ciò non fosse necessario la parte con END
e tutto ciò che segue (all'interno delle virgolette singole) può essere rimosso.
Se hai terminazioni di riga in stile Windows/DOS (\r\n
), devi convertirli in stile UNIX (\n
) primo. Per fare questo puoi inserire tr -d '\015'
all'inizio della pipeline:
tr -d '\015' < /path/to/input.list | awk […] > /path/to/output
(Supponendo che tu non abbia alcuna utilità per \r
è nel tuo file. Presupposto molto sicuro qui.)
In alternativa, esegui semplicemente dos2unix /path/to/input.list
una volta per convertire il file sul posto.
Come mostra la risposta collegata di @don_crissti, l'opzione incolla rasenta l'incredibile velocità:il piping del kernel Linux è più efficiente di quanto avrei creduto se non l'avessi provato solo ora. Sorprendentemente, se puoi accontentarti di una singola virgola che separa gli elementi dell'elenco anziché di una virgola+spazio, una pipeline di incolla
(paste -d\' /dev/null - /dev/null | paste -sd, -) <input
è più veloce anche di un ragionevole flex
programma(!)
%option 8bit main fast
%%
.* { printf("'%s'",yytext); }
\n/(.|\n) { printf(", "); }
Ma se solo prestazioni decenti sono accettabili (e se non stai eseguendo uno stress test, non sarai in grado di misurare alcuna differenza di fattore costante, sono tutte istantanee) e vuoi sia flessibilità con i tuoi separatori che ragionevole -liner-y-ness,
sed "s/.*/'&'/;H;1h;"'$!d;x;s/\n/, /g'
è il tuo biglietto Sì, sembra un rumore di linea, ma il H;1h;$!d;x
l'idioma è il modo giusto per assorbire tutto, una volta che puoi riconoscere che l'intera cosa diventa davvero facile da leggere, è s/.*/'&'/
seguito da uno slurp e da un s/\n/, /g
.
modifica:al limite dell'assurdo, è abbastanza facile ottenere flessibilità per battere tutto il resto vuoto, basta dire a stdio che non hai bisogno della sincronizzazione multithread/signalhandler incorporata:
%option 8bit main fast
%%
.+ { putchar_unlocked('\'');
fwrite_unlocked(yytext,yyleng,1,stdout);
putchar_unlocked('\''); }
\n/(.|\n) { fwrite_unlocked(", ",2,1,stdout); }
e sotto stress è 2-3 volte più veloce delle pipeline di pasta, che sono esse stesse almeno 5 volte più veloci di qualsiasi altra cosa.