Sostituzione del trattino basso con virgola e rimozione delle virgolette doppie in CSV


10

Ho un file CSV come

input.csv

"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
"1_1_0_0_79"
"1_1_0_0_80"
"1_1_0_0_81"
"1_1_0_0_82"
"1_1_0_0_83"
"1_1_0_0_84"
"1_1_0_0_85"

............. e così via.

Devo convertire questo file CSV in

result.csv 

1,1,0,0,76
1,1,0,0,77
1,1,0,0,78
1,1,0,0,79
1,1,0,0,80
1,1,0,0,81
1,1,0,0,82
1,1,0,0,83
1,1,0,0,84
1,1,0,0,85

Risposte:


24

Il modo molto più semplice è usare tr

$ tr '_' ',' < input.csv | tr -d '"'                  
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

Il modo in cui funziona è che trrichiede due argomenti: set di caratteri da sostituire e loro sostituzione. In questo caso abbiamo solo set di 1 carattere. Reindirizziamo il flusso stdin input.csvdell'input trtramite l' <operatore shell e reindirizziamo l'output risultante tr -d '"'per eliminare le virgolette doppie.

Ma awkpuò farlo anche.

$ cat input.csv
"1_1_0_0_76"
"1_1_0_0_77"
"1_1_0_0_78"
$ awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

Il modo in cui funziona è leggermente diverso: awk legge ogni file riga per riga, essendo ogni script in linea /Pattern match/{ codeblock}/Another pattern/{code block for this pattern}. Qui non abbiamo un modello, quindi significa eseguire il codeblock per ogni riga. gsub()La funzione viene utilizzata per la sostituzione globale all'interno di una riga, quindi la usiamo per sostituire i trattini bassi con virgole e le doppie virgolette con una stringa nulla (eliminando efficacemente il carattere). Il 1è al posto del pattern match con mancante blocco di codice, il cui valore predefinito semplicemente alla stampa la linea; in altre parole il codeblock con gsub()fa il lavoro e 1stampa il risultato.

Utilizzare il reindirizzamento della shell ( >) per inviare l'output a un nuovo file:

 awk '{gsub(/_/,",");gsub(/\"/,"")};1' input.csv > output.csv

Mi sono anche chiesto di rimuovere anche le virgolette. Ho aggiornato la domanda
RKR

@RKR Risposta aggiornata di conseguenza, anche la risposta di Ian viene aggiornata
Sergiy Kolodyazhnyy,

13

Proprio come alternativa, puoi anche usare questo sedcomando:

$ sed -e 's/_/,/g' -e 's/"//g' input.csv
1,1,0,0,76
1,1,0,0,77
1,1,0,0,78

1
All'interno di virgolette singole, non è necessario evitare una doppia virgoletta.
Glenn Jackman,

Effettivamente @glennjackman! Ho appena rimosso la barra rovesciata in fuga
IanC

10

Anche Perl, la "motosega dell'esercito svizzero" dell'elaborazione del testo da riga di comando, può farlo. La sintassi è (non a caso) abbastanza simile agli esempi tre sed:

perl -pe 'tr/_"/,/d' input.csv > result.csv

o:

perl -pe 's/_/,/g; s/"//g' input.csv > result.csv

Ma onestamente, se non vuoi prenderti il ​​tempo per imparare un nuovo linguaggio di programmazione (che è davvero ciò che sono awk, Perl e sed e altri strumenti come loro) proprio per questo compito di base, potresti anche farlo in qualsiasi editor di testo che supporti la ricerca e la sostituzione:

  1. Apri il file CSV nel tuo editor di testo preferito (come gedit, kate, mousepad, ecc .; anche il semplice vecchio Blocco note o Wordpad su Windows può farlo).

  2. Seleziona "Cerca e sostituisci" dal menu (in genere si trova sotto "Modifica", se non esiste un menu "Cerca" separato).

  3. Entra _nella casella di ricerca e ,nella casella di sostituzione.

  4. Fai clic su "Sostituisci tutto".

  5. Ripeti con "nella casella di ricerca e niente nella casella di sostituzione.

  6. Salva il file.

Ora, se è necessario eseguire questa operazione per 100 o 1000 file anziché solo uno, l'apprendimento di un nuovo strumento da riga di comando inizia a dare un senso. E, naturalmente, una volta che sai come usare Perl o sed o altro, risparmierai molto tempo e fatica con attività simili in seguito. Ma per un lavoro unico che non ti aspetti di dover ripetere, a volte uno strumento interattivo di base come un editor di testo è la soluzione più semplice.


3

Potresti farlo anche tu vim.

Apri il file:, vim input.csvquindi usa lo vimstrumento di ricerca avanzata s. Digita due punti ( :) per accedere alla modalità comandi ed esegui comandi in questo modo:

:%s's/_/,/g'  -- Replaces all occurrences of _ with , in the current file.
:s/\"//g -- Replaces all occurrences of " with nothing in the current file.

Praticamente gli stessi comandi della risposta di IanC, ma dentro viminvece di usare sed.


2

Perché non modificare semplicemente i valori predefiniti dei valori di Separatore di input e output

awk -F "_" 'BEGIN { OFS="," }; {gsub(/\"/,""); print $1,$2,$3,$4,$5}' input.csv
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.