GNU/Linux >> Znalost Linux >  >> Linux

Přeměna samostatných řádků na čárkami oddělený seznam s položkami v uvozovkách

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.

Poznámka

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í.


Linux
  1. Vložit nové řádky s chybějícími hodnotami (ne)?

  2. Rozdělení výstupu do nových řádků?

  3. Jak dostat Ls do seznamu adresářů s koncovým lomítkem?

  1. Jak extrahovat/změnit řádky v textovém souboru, jehož data jsou rozdělena do polí?

  2. Používáte zalamování slov s Mc?

  3. Jdi do toho – moderní seznam úkolů s časovačem

  1. Jak spojit více řádků názvů souborů do jednoho s vlastním oddělovačem?

  2. Převedení více řádků do jednoho řádku odděleného čárkou

  3. Použití seznamu povolených uživatelů s VSFTPD