C'è un modo per utilizzare bash per rimuovere le ultime quattro colonne per alcuni file CSV di input? Le ultime quattro colonne possono avere campi di lunghezza variabile da linea a linea, quindi non è sufficiente cancellare solo un certo numero di caratteri dalla fine di ogni riga.metodo bash per rimuovere le ultime 4 colonne dal file csv
risposta
Taglia può farlo se tutte le linee hanno lo stesso numero di campi o awk se non lo fai.
cut -d, -f1-6 # assuming 10 fields
stamperà i primi 6 campi, se si desidera controllare l'utilizzo di uscita seperater --output-delimitatore = stringa
awk -F , -v OFS=, '{ for (i=1;i<=NF-4;i++){ printf $i, }; printf "\n"}'
Loops su campi fino a th numero di campi -4 e stampe fuori.
È possibile utilizzare cut
per questo se si conosce il numero di colonne. Ad esempio, se il file ha 9 colonne, e la virgola è il vostro delimitatore:
cut -d',' -f -5
Tuttavia, questo assume i dati nel file CSV non contiene virgole. cut
interpreterà le virgole anche all'interno delle virgolette come delimitatori.
awk one-liner:
awk -F, '{for(i=0;++i<=NF-5;)printf $i", ";print $(NF-4)}' file.csv
il vantaggio di utilizzare awk sopra taglio è, non c'è bisogno di contare quante colonne avete e quante colonne si desidera conservare. Dal momento che quello che vuoi è rimuovere le ultime 4 colonne.
vedere il test:
kent$ seq 40|xargs -n10|sed 's/ /, /g'
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
11, 12, 13, 14, 15, 16, 17, 18, 19, 20
21, 22, 23, 24, 25, 26, 27, 28, 29, 30
31, 32, 33, 34, 35, 36, 37, 38, 39, 40
kent$ seq 40|xargs -n10|sed 's/ /, /g' |awk -F, '{for(i=0;++i<=NF-5;)printf $i", ";print $(NF-4)}'
1, 2, 3, 4, 5, 6
11, 12, 13, 14, 15, 16
21, 22, 23, 24, 25, 26
31, 32, 33, 34, 35, 36
Questo potrebbe funzionare per voi (GNU sed):
sed -r 's/(,[^,]*){4}$//' file
Nel mio senso, è la migliore risposta qui! –
cat data.csv | rev | cut -d, -f-5 | rev
rev
inverte le linee, in modo che non importa se tutte le righe avere lo stesso numero di colonne, rimuoverà sempre l'ultimo 4. Funziona solo se le ultime 4 colonne non contengono le virgole stesse.
Questa è una soluzione davvero bella a mio avviso, +1 per l'uso di rev (non sapevo che esistesse) – skd
Questa soluzione awk in modo compromessi
awk -F, 'OFS=","{for(i=NF; i>=NF-4; --i) {$i=""}}{gsub(",,,,,","",$0);print $0}' temp.txt
awk -F, '{NF-=4; OFS=","; print}' file.csv
oppure
awk -F, -vOFS=, '{NF-=4;print}' file.csv
cadrà ultime 4 colonne da ogni riga.
Un buon modo per rilasciare le colonne extra, ma per me questo sostituisce le virgole tra le colonne con gli spazi nell'output . C'è un modo semplice per evitarlo e tenerli come virgole? –
È possibile aggiungere nuovamente il delimitatore con awk -F, '{NF- = 4; OFS = ""; print} ' –
Ottimo, funziona per me. Inoltre, è possibile impostare 'OFS' in un blocco' BEGIN' o con l'argomento '-v' della riga di comando come' awk -F, -vOFS =, ... ' –
nella riga di awk, suppongo che tu voglia printf $ non stampare $ i, giusto? errore di battitura forse? e 'print $ i,' non funzionerà, potresti voler avere ';' un altro errore di battitura? – Kent
@kent yeah significava printf $ i, non è necessario avere il; se solo un comando. – peteches
hai ragione, ma hai "virgola" .. :) – Kent