2013-01-19 31 views
9

Czy istnieje sposób użycia bash do usunięcia ostatnich czterech kolumn dla jakiegoś wejściowego pliku CSV? Ostatnie cztery kolumny mogą mieć pola, które różnią się długością od linii do linii, więc nie wystarczy po prostu usunąć określoną liczbę znaków od końca każdego wiersza.Metoda bash do usunięcia ostatnich 4 kolumn z pliku CSV

Odpowiedz

12

Wytnij można to zrobić, jeśli wszystkie wiersze mają taką samą liczbę pól lub awk, jeśli nie.

cut -d, -f1-6 # assuming 10 fields 

wypisze pierwsze 6 pól, jeśli chcesz kontrolować korzystanie wyjście seperater --output-separator = łańcuch

awk -F , -v OFS=, '{ for (i=1;i<=NF-4;i++){ printf $i, }; printf "\n"}' 

Loops nad polami do th liczbę pól -4 i wydruki je.

+0

w linii awk, myślę, że chcesz wydrukować $ i nie wydrukować $ i, prawda? może literówka? i 'print $ i,' nie zadziała, możesz chcieć mieć ';' jeszcze jedną literówkę? – Kent

+0

@kent tak oznaczało printf $ i, nie musisz mieć; jeśli tylko jedno polecenie. – peteches

+0

masz rację, ale masz "przecinek" .. :) – Kent

6

Możesz użyć do tego celu cut, jeśli znasz liczbę kolumn. Na przykład, jeśli plik ma 9 kolumn, a przecinek to separator:

cut -d',' -f -5 

Jednak ta zakłada dane w pliku csv nie zawiera żadnych przecinków. cut interpretuje również przecinki wewnątrz cudzysłowów jako ograniczniki.

1

awk jedno-liner:

awk -F, '{for(i=0;++i<=NF-5;)printf $i", ";print $(NF-4)}' file.csv 

Zaletą korzystania z awk na cięcie jest, nie trzeba się liczyć, ile kolumn masz i ile kolumn, które chcesz zachować. Ponieważ chcesz usunąć ostatnie 4 kolumny.

zobaczyć 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 
1

To może pracować dla Ciebie (GNU sed):

sed -r 's/(,[^,]*){4}$//' file 
+0

. W moim rozumieniu jest to najlepsza odpowiedź tutaj! –

10
cat data.csv | rev | cut -d, -f-5 | rev 

rev odwraca linii, więc nie ma znaczenia, czy wszystkie wiersze mają taką samą liczbę kolumn, to zawsze usunie ostatnie 4. Działa to tylko wtedy, gdy ostatnie 4 kolumny nie zawierają samych przecinków.

+2

To jest naprawdę fajne rozwiązanie, moim zdaniem, +1 do używania rev (nie wiedziałem, że istnieje) – skd

1

To rozwiązanie awk w hakera sposób

awk -F, 'OFS=","{for(i=NF; i>=NF-4; --i) {$i=""}}{gsub(",,,,,","",$0);print $0}' temp.txt 
3
awk -F, '{NF-=4; OFS=","; print}' file.csv 

lub alternatywnie

awk -F, -vOFS=, '{NF-=4;print}' file.csv 

spadnie ostatnie 4 kolumny z każdej linii.

+0

Dobry sposób na upuszczenie dodatkowych kolumn, ale dla mnie to zastępuje przecinki między kolumnami spacjami w wynikach . Czy istnieje prosty sposób na uniknięcie tego i zachowanie ich jako przecinków? –

+0

Możesz dodać z powrotem ogranicznik za pomocą awk-F, '{NF- = 4; OFS = ","; print} ' –

+0

Świetnie, to działa dla mnie. Może również ustawić 'OFS' w bloku' BEGIN' lub z argumentem wiersza poleceń '-v' jak' awk -F, -vOFS =, ... ' –