Estrai i dati da un file e inseriscili in file diversi in base al valore di una colonna


14

Genereremo un file CSV con i seguenti valori

yp1234,577,1,3
yp5678,577,3,5
yp9012,132,8,9

Devo estrarre i dati e creare file in base alla seconda colonna. Se è 577, l'intera riga deve essere estratta e posizionata in un file separato. Voglio dire, ho bisogno di un file con righe con la seconda colonna come solo 577 e un altro file con la seconda colonna come solo 132

Ho provato a usare IF ma non ha funzionato


5
In realtà pubblicare il codice che non funziona è sempre una buona idea.
Riccioli d'oro,

Risposte:


27

Utilizzare awk:

awk -F, '{ print > $2 ".csv" }' file.csv

Questo creerà i due file 577.csve 132.csvnella tua directory corrente.

Il comando sopra presuppone che tu possa avere solo 132o 577come secondo campo. Creerà un nome file per ciascuno dei valori trovati nel secondo campo dell'intero file.csv.

Se ci sono altri valori oltre ai due che ti interessano e vuoi ignorare quelle righe, fai invece questo:

awk -F, '$2 == "577" || $2 == "132" { print > $2 ".csv" }' file.csv

1
Esistono awkimplementazioni errate che non possono essere utilizzate print > $2 ".cvs". Su questi, si dovrà prima calcolare il nome del file, poi fare il print: fname = $2 ".cvs"; print > fname.
Kusalananda

3

Mi piace la awksoluzione di Terdon , ma per completezza, ecco un suggerimento che usa solobash

while IFS=, read -r a1 a2 a3 a4; do 
    echo "$a1,$a2,$a3,$a4" >> "$a2".csv
done < file.csv

Produrrà file 577.csve 132.csvnella directory corrente.


3

Per estrarre tutti i 577 su stdout

grep -e '^.*,577,.*,.*$' youfile.csv >result_extract_557.csv

- modifica 1 Corretto, basato sul commento di @ terdon di seguito per evitare false corrispondenze quando almeno 3 virgole in linea con 577.

grep -e '^[:alnum:]*,577,[:digit:]*,[:digit:]*$' youfile.csv >result_extract_557.csv

Ma penso che la sua awksoluzione sia più completa.


Ciò corrisponderà anche se 577 si trova su un altro campo, non sul secondo o se fa parte di un campo. Ad esempio foo577baro yp9012,132,8,577.
terdon

Pensavo che le mie virgole avrebbero reso la posizione sul campo dipendente?
X Tian,

Siamo spiacenti, ho fornito esempi errati, ma .*posso anche abbinare le virgole in modo da non sapere quale campo stai abbinando. Potrebbe essere il secondo, potrebbe anche essere il 45 °. La mia seconda lamentela era sbagliata, hai ragione che le virgole proteggono dalla corrispondenza foo577bar.
terdon

cosa fare se | viene utilizzato il carattere anziché,.
user3116123

ricezione sotto errore grep: opzione illegale - e Utilizzo: grep -hblcnsviw file di modello. . .
user3116123

1

Utilizzando csvkit:

$ csvgrep -c 2 -m 577 data.csv >output.csv

Le -c 2marche cvsgrepconsiderano la seconda colonna e con -m 577chiediamo che corrisponda alla stringa 577in quella colonna.

Il seguente sarà scritto a output.csv:

yp1234,577,1,3
yp5678,577,3,5

Per abbinare un numero di stringhe e scrivere l'output in un file per ogni stringa:

for pattern in 577 132; do
  csvgrep -c 2 -m "$pattern" data.csv >"output-$pattern.csv"
done

Questo creerà i due file output-132.csve output-577.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.