Vous pouvez ajouter des guillemets avec sed puis fusionner les lignes avec coller , comme ça :
sed 's/^\|$/"/g'|paste -sd, -
Si vous utilisez un système basé sur GNU coreutils (c'est-à-dire Linux), vous pouvez omettre le '-'
final .
Si vos données d'entrée ont des fins de ligne de style DOS (comme suggéré par @phk), vous pouvez modifier la commande comme suit :
sed 's/\r//;s/^\|$/"/g'|paste -sd, -
Utilisation de
awk
:awk 'BEGIN { ORS="" } { print p"'"'"'"$0"'"'"'"; p=", " } END { print "\n" }' /path/to/list
Alternative avec moins de shell s'échappant et donc plus lisible :awk 'BEGIN { ORS="" } { print p"\047"$0"\047"; p=", " } END { print "\n" }' /path/to/list
Sortie :'d3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Explication:
Le awk
le script lui-même sans tous les échappements est BEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Après avoir imprimé la première entrée la variable p
est défini (avant cela, c'est comme une chaîne vide). Avec cette variable p
chaque entrée (ou en awk
-parler :enregistrer ) est préfixé et imprimé en plus avec des guillemets simples autour. Le awk
variable de séparateur d'enregistrement de sortie ORS
n'est pas nécessaire (puisque le préfixe le fait pour vous) donc il est défini pour être vide au BEGIN
ing. Oh et nous pourrions notre fichier à END
avec une nouvelle ligne (par exemple, pour que cela fonctionne avec d'autres outils de traitement de texte); si cela n'est pas nécessaire, la partie avec END
et tout ce qui suit (à l'intérieur des guillemets simples) peut être supprimé.
Si vous avez des fins de ligne de style Windows/DOS (\r\n
), vous devez les convertir en style UNIX (\n
) première. Pour cela vous pouvez mettre tr -d '\015'
au début de votre pipeline :
tr -d '\015' < /path/to/input.list | awk […] > /path/to/output
(En supposant que vous n'ayez aucune utilité pour \r
s dans votre dossier. Hypothèse très sûre ici.)
Sinon, exécutez simplement dos2unix /path/to/input.list
une fois pour convertir le fichier sur place.
Comme le montre la réponse liée de @ don_crissti, l'option de collage est incroyablement rapide - la tuyauterie du noyau Linux est plus efficace que je ne l'aurais cru si je ne l'avais pas essayé tout à l'heure. Remarquablement, si vous pouvez vous contenter d'une seule virgule séparant les éléments de votre liste plutôt qu'une virgule + espace, un pipeline de collage
(paste -d\' /dev/null - /dev/null | paste -sd, -) <input
est plus rapide que même un flex
raisonnable programme (!)
%option 8bit main fast
%%
.* { printf("'%s'",yytext); }
\n/(.|\n) { printf(", "); }
Mais si des performances décentes sont acceptables (et si vous n'exécutez pas de test de résistance, vous ne pourrez mesurer aucune différence de facteur constant, elles sont toutes instantanées) et que vous voulez à la fois de la flexibilité avec vos séparateurs et un raisonnable -liner-y-ness,
sed "s/.*/'&'/;H;1h;"'$!d;x;s/\n/, /g'
est votre billet. Oui, cela ressemble à du bruit de ligne, mais le H;1h;$!d;x
l'idiome est la bonne façon de tout avaler, une fois que vous pouvez reconnaître que tout devient vraiment facile à lire, c'est s/.*/'&'/
suivi d'un slurp et d'un s/\n/, /g
.
edit :à la limite de l'absurde, il est assez facile d'obtenir flex pour battre tout le reste creux, dites simplement à stdio que vous n'avez pas besoin de la synchronisation intégrée multithread/signalhandler :
%option 8bit main fast
%%
.+ { putchar_unlocked('\'');
fwrite_unlocked(yytext,yyleng,1,stdout);
putchar_unlocked('\''); }
\n/(.|\n) { fwrite_unlocked(", ",2,1,stdout); }
et sous contrainte, c'est 2 à 3 fois plus rapide que les pipelines de pâte, qui sont eux-mêmes au moins 5 fois plus rapides que tout le reste.