jeśli mam plik csv w następującym formacie:
column1,column2,column3,column4,column5,column6,column7,column8
i chcę, aby awk
drukowało tylko kolumny od 2 do 7, których użyłbym:
awk -F"," "{print $2 "," $3 "," $4 "," $5 "," $6 "," $7}" file.csv
i get:
column2,column3,column4,column5,column6,column7
Czy istnieje sposób na konkatenację kolumn 2-7 w celu uproszczenia polecenia. Ponieważ myślę o pliku z nieco większą liczbą kolumn, moje polecenie awk
stałoby się strasznie długie.
Komentarze
- czy zawsze będziesz potrzebować kolejnego zestawu kolumn (np. 2-7, 5-15 lub cokolwiek)? jeśli tak, możesz użyć pętli do wydrukowania kolumn. Jeśli nie, ' nie omija listy poszczególnych kolumn, które chcesz (chociaż w razie potrzeby możesz mieszać w niektórych pętlach). Ponadto, ile kolumn?
- Na koniec możesz chcieć rozważać język taki jak perl lub python z dobrym parserem CSV …. zwłaszcza jeśli masz nazwy kolumn w pierwszym wierszu (kilka z ' perlowych modułów parsujących CSV może używać te tworzą hash z nazwami kolumn jako kluczami. i ' m całkiem pewny, że python ' s parsery CSV mogą robić podobnie). perl ma również doskonałą tablicę & operatory splicingu hash.
- @cas tak, kolumny będą alwa ys konsekutywnie.
- Czy to odpowiada na Twoje pytanie? Wydrukuj zakres kolumn oddzielonych przecinkami, a resztę bez oddzielania przecinkami
Odpowiedź
$ awk -v b=2 -v e=7 "BEGIN{FS=OFS=","} {for (i=b;i<=e;i++) printf "%s%s", $i, (i<e ? OFS : ORS)}" file column2,column3,column4,column5,column6,column7
b = numer pola początkowego, e = numer pola końcowego. Jeśli potrzebujesz obsługiwać pliki CSV z polami w cudzysłowach, osadzonymi przecinkami, znakami nowej linii itp., Zobacz https://stackoverflow.com/q/45420535/1745001 .
Odpowiedź
Wycięcie narzędzia ma zwarty zapis:
cut -d, -f2-7 <input-file>
wytwarzam:
kolumna2, kolumna3, kolumna4, kolumna5, kolumna6, kolumna7
Odpowiadając na komentarz @PlasmaBinturong: moim zamiarem było rozwiązanie problemu krótkiej sekwencji wywołania: " … moje polecenie awk byłoby strasznie długie … ". Jednak można również znaleźć kody, które układają pola według własnego uznania. Chociaż lubię awk, perl, python, często uważam, że warto zbudować specjalne narzędzie, które rozszerzy możliwości standardu * nix. Oto fragment skryptu testowego, s2, pokazujący narzędzia do ponownego wyrównywania i układania, oba pozwalają na zmianę układu i powielanie, przy czym aranżacja umożliwia również zmniejszanie zakresów pól:
FILE=${1-data1} # Utility functions: print-as-echo, print-line-with-visual-space. pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } pl " Input data file $FILE:" head $FILE pl " Results, cut:" cut -d, -f2-7 $FILE pl " Results, recut (modified as my-recut):" my-recut -d "," 7,6,2-5 < $FILE pl " Results, arrange:" arrange -s "," -f 5,3-1,7,5,3-4,5 $FILE
produkując wyniki z tych wersji:
OS, ker|rel, machine: Linux, 3.16.0-10-amd64, x86_64 Distribution : Debian 8.11 (jessie) bash GNU bash 4.3.30 cut (GNU coreutils) 8.23 recut - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) arrange (local) 1.15 ----- Input data file data1: column1,column2,column3,column4,column5,column6,column7,column8 ----- Results, cut: column2,column3,column4,column5,column6,column7 ----- Results, recut (modified as my-recut): column7,column6,column2,column3,column4,column5 ----- Results, arrange: column5,column3,column2,column1,column7,column5,column3,column4,column5
my-recut jest niewielką modyfikacją powtórzonego kodu textutils, a aranżacja to nasza wersja rozszerzonego cięcia . Więcej informacji:
recut Process fields like cut, allow repetitions and re-ordering. (what) Path : ~/bin/recut Version : - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) Length : 56 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Home : http://www1.cuni.cz/~obo/textutils/ (doc) Modules : (for perl codes) Getopt::Long 2.42 arrange Arrange fields, like cut, but in user-specified order. (what) Path : ~/bin/arrange Version : 1.15 Length : 355 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Modules : (for perl codes) warnings 1.23 strict 1.08 Carp 1.3301 Getopt::Euclid 0.4.5
Pozdrawiam … Pozdrawiam, drl
Komentarze
- W przeciwieństwie do Awk, wypisuje kolumny w kolejności pliku wejściowego, a nie w kolejności poleceń.
- @PlasmaBinturong – patrz edytowana odpowiedź … okrzyki
Odpowiedź
sed -e " s/,/\n/7 ;# tag the end of col7 s/^/,/ ;# add a comma s/,/\n/2 ;# tag beginning of col2 s/.*\n\(.*\)\n.*/\1/ ;# perform surgery " file.csv
Wyniki:
column2,column3,column4,column5,column6,column7
Odpowiedź
Przetestowano poniższym poleceniem i działało dobrze
awk -F "," "OFS=","{$1="";$NF="";print $0}" o| sed "s/^,//g"|sed "s/,$//g"
wyjście
column2,column3,column4,column5,column6,column7
Komentarze
- dziękuję za odpowiedź, działa dobrze bez " o " przed pierwszym
sed
potokiem 🙂 można połączyć dwa poleceniased
w jedno:sed "s/^,//g; s/,$//g"
- Dlaczego testujesz wynik wykonania
zdecydować, czy wydrukować linię? Są też inne problemy (np. NIE potrzebujesz potoków do poleceń seda, gdy ' używasz awk!), Ale ta część testowa OFS nie ma absolutnie żadnego sensu …
awk
rozwiązanie … cut
, które opublikował @drl ? awk
i byłem raczej zaciekawiony z powodów technicznych 🙂