Pomocí sed můžete přidat uvozovky a poté sloučit řádky pomocí vložit , takhle:
sed 's/^\|$/"/g'|paste -sd, -
Pokud používáte systém založený na GNU coreutils (tj. Linux), můžete vynechat koncové '-'
.
Pokud zadaná data mají zakončení řádků ve stylu DOS (jak navrhl @phk), můžete příkaz upravit následovně:
sed 's/\r//;s/^\|$/"/g'|paste -sd, -
Pomocí
awk
:awk 'BEGIN { ORS="" } { print p"'"'"'"$0"'"'"'"; p=", " } END { print "\n" }' /path/to/list
Alternativa s menším únikem shellu, a proto čitelnější:awk 'BEGIN { ORS="" } { print p"\047"$0"\047"; p=", " } END { print "\n" }' /path/to/list
Výstup:'d3heatmap', 'data.table', 'ggplot2', 'htmltools', 'htmlwidgets', 'metricsgraphics', 'networkD3', 'plotly', 'reshape2', 'scales', 'stringr'
Vysvětlení:
awk
samotný skript bez jakéhokoli escapování je BEGIN { ORS="" } { print p"'"$0"'"; p=", " } END { print "\n" }
. Po vytištění prvního záznamu proměnná p
je nastaven (předtím je to jako prázdný řetězec). S touto proměnnou p
každý záznam (nebo v awk
-speak:záznam ) má předponu a je navíc vytištěno jednoduchými uvozovkami. awk
výstupní proměnná oddělovače záznamů ORS
není potřeba (protože to dělá předpona za vás), takže je nastavena jako prázdná na BEGIN
Ing. Jo a můžeme náš soubor na END
s novým řádkem (např. takže funguje s dalšími nástroji pro zpracování textu); pokud to není potřeba, část s END
a vše za ním (uvnitř jednoduchých uvozovek) lze odstranit.
Pokud máte zakončení řádků ve stylu Windows/DOS (\r\n
), musíte je převést do stylu UNIX (\n
) První. Chcete-li to provést, můžete zadat tr -d '\015'
na začátku vašeho kanálu:
tr -d '\015' < /path/to/input.list | awk […] > /path/to/output
(Za předpokladu, že pro \r
nemáte žádné využití s ve vašem souboru. Zde je velmi bezpečný předpoklad.)
Případně jednoduše spusťte dos2unix /path/to/input.list
jednou pro převod souboru na místě.
Jak ukazuje propojená odpověď @don_crissti, možnost vložení hraničí s neuvěřitelně rychlou rychlostí - potrubí linuxového jádra je efektivnější, než bych věřil, kdybych to právě teď nezkusil. Je pozoruhodné, že pokud můžete být spokojeni s jedinou čárkou oddělující položky seznamu namísto čárky + mezery, potrubí pro vkládání
(paste -d\' /dev/null - /dev/null | paste -sd, -) <input
je dokonce rychlejší než rozumné flex
program(!)
%option 8bit main fast
%%
.* { printf("'%s'",yytext); }
\n/(.|\n) { printf(", "); }
Pokud je však přijatelný pouze slušný výkon (a pokud neprovádíte zátěžový test, nebudete moci změřit žádné rozdíly konstantního faktoru, všechny jsou okamžité) a chcete jak flexibilitu s oddělovači, tak přiměřenou -liner-y-ness,
sed "s/.*/'&'/;H;1h;"'$!d;x;s/\n/, /g'
je vaše vstupenka. Ano, vypadá to jako řádkový šum, ale H;1h;$!d;x
idiom je tím správným způsobem, jak všechno shrnout, jakmile zjistíte, že celá věc je skutečně snadno čitelná, je to s/.*/'&'/
následuje slurp a s/\n/, /g
.
edit:hraničící s absurditou, je docela snadné získat flex, abyste porazili všechno ostatní duté, stačí říct stdio, že nepotřebujete vestavěnou synchronizaci multithread/signalhandler:
%option 8bit main fast
%%
.+ { putchar_unlocked('\'');
fwrite_unlocked(yytext,yyleng,1,stdout);
putchar_unlocked('\''); }
\n/(.|\n) { fwrite_unlocked(", ",2,1,stdout); }
a ve stresu je to 2-3x rychlejší než potrubí pro pastu, které jsou samy o sobě minimálně 5x rychlejší než všechno ostatní.