Wyodrębnij określone kolumny z oddzielonego pliku za pomocą Awk
Przepraszam, jeśli to zbyt proste. Mam plik csv, gdzie kolumny mają wiersz nagłówka (v1, v2, itp.). Rozumiem, że aby wyodrębnić Kolumny 1 i 2, muszę zrobić: awk -F "," '{print $1 "," $2}' infile.csv > outfile.csv
. Ale co jeśli będę musiał wyodrębnić kolumny od 1 do 10, 20 do 25 i 30, 33? Jako dodatek, czy jest jakiś sposób, aby wyodrębnić bezpośrednio z nazw nagłówków, a nie z numerów kolumn?
8 answers
Nie wiem czy da się zrobić zakresy w awk. Możesz zrobić pętlę for, ale musisz dodać obsługę, aby odfiltrować kolumny, których nie chcesz. Chyba łatwiej to zrobić:
awk -F, '{OFS=",";print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$20,$21,$22,$23,$24,$25,$30,$33}' infile.csv > outfile.csv
Coś innego do rozważenia - a to szybsze i bardziej zwięzłe:
cut -d "," -f1-10,20-25,30-33 infile.csv > outfile.csv
Jeśli chodzi o drugą część twojego pytania, prawdopodobnie napisałbym skrypt w Perlu, który wie, jak obsługiwać wiersze nagłówków, analizując nazwy kolumn ze standardowego wejścia lub pliku, a następnie filtrując. On prawdopodobnie narzędzie, które chciałbym mieć do innych rzeczy. Nie jestem pewien, co do robienia w jednym linerze, chociaż jestem pewien, że da się to zrobić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 03:09:18
Jak wspomniał @Tom, podejście cut i awk faktycznie nie działa dla CSV z cytowanymi ciągami. Alternatywą jest moduł Pythona, który dostarcza narzędzie wiersza poleceń csvfilter. Działa jak cut, ale poprawnie obsługuje cytowanie kolumny CSV:
csvfilter -f 1,3,5 in.csv > out.csv
Jeśli masz Pythona (i powinieneś), możesz go zainstalować po prostu tak:
pip install csvfilter
Proszę zauważyć, że indeksowanie kolumn w csvfilter zaczyna się od 0(w przeciwieństwie do awk, który zaczyna się od $1). Więcej informacji na https://github.com/codeinthehole/csvfilter/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-04 11:49:15
Inni odpowiedzieli na twoje wcześniejsze pytanie. Za to:
Jako dodatek, czy jest jakiś sposób na wyodrębnienie bezpośrednio z nazw nagłówków, a nie z numerów kolumn?
Nie próbowałem go, ale można przechowywać indeks każdego nagłówka w hash, a następnie użyć tego hasha, aby uzyskać jego indeks później.
for(i=0;i<$NF;i++){
hash[$i] = i;
}
Potem użyj go:
j = hash["header1"];
print $j;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-25 04:40:28
Inne języki mają skróty dla zakresów numerów pól, ale nie awk, będziesz musiał napisać swój kod jako swój strach; -)
awk -F, 'BEGIN {OFS=","} { print $1, $2, $3, $4 ..... $30, $33}' infile.csv > outfile.csv
Nie ma bezpośredniej funkcji w awk, która używałaby nazw pól jako określeń kolumn.
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 03:05:34
Możesz użyć pętli for, aby zaadresować pole za pomocą $i :
ls -l | awk '{for(i=3 ; i<8 ; i++) {printf("%s\t", $i)} print ""}'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-22 06:11:47
Tabulator jest zestawem uniksowych narzędzi wiersza poleceń do pracy z plikami csv, które mają linie nagłówka. Oto przykład wyodrębnienia kolumn według nazwy z pliku test.csv:
name,sex,house_nr,height,shoe_size
arthur,m,42,181,11.5
berta,f,101,163,8.5
chris,m,1333,175,10
don,m,77,185,12.5
elisa,f,204,166,7
Następnie tblmap -k name,height test.csv
tworzy
name,height
arthur,181
berta,163
chris,175
don,185
elisa,166
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-04 07:52:40
Jeśli Perl jest opcją:
perl -F, -lane 'print join ",",@F[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32]'
-a
autosplits line into @F
Fields array. Indeksy zaczynają się od 0 (nie 1 Jak w awk)-F,
separatorem pola jest,
Jeśli plik CSV zawiera przecinki w cudzysłowach, pełnowartościowe parsery CSV, takie jak Perl Text::CSV_XS
, są specjalnie stworzone do obsługi tego rodzaju dziwactwa.
perl -MText::CSV_XS -lne 'BEGIN{$csv=Text::CSV_XS->new()} if($csv->parse($_)){@f=$csv->fields();print (join ",",@f[0,1,2,3,4,5,6,7,8,9,19,20,21,22,23,24,29,32])}'
Podałem więcej wyjaśnień w mojej odpowiedzi tutaj: parse csv file using gawk
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:17:44
Nie używam awk, ale najprostszym sposobem, w jaki udało mi się to zrobić, było użycie csvtool. Miałem również inne przypadki użycia, Aby użyć csvtool i może obsługiwać cudzysłowy lub ograniczniki odpowiednio, jeśli pojawiają się one w samych danych kolumn.
csvtool format '%(2)\n' input.csv
csvtool format '%(2),%(3),%(4)\n' input.csv
Zastąpienie 2 numerem kolumny skutecznie wyodrębni dane kolumny, których szukasz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 18:39:27