AWK – wypisuje zakres kolumn

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 polecenia sed 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 …

  • @EdMorton I ' nadal mam nadzieję na jedyne awk rozwiązanie …
  • @nath why ? Co ' jest nie tak z rozwiązaniem cut, które opublikował @drl ?
  • @EdMorton nie, masz rację, działa dobrze. Pomyślałem, że nie może to być zbyt skomplikowane w przypadku awk i byłem raczej zaciekawiony z powodów technicznych 🙂
  • Dodaj komentarz

    Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *