Pytanie o awk


9

Ok, ponieważ jest to złożone pytanie, wyjaśnię je jasno. Mam zawartość pliku pokazaną jak poniżej:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

Dane wyjściowe, które chcę

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

Najpierw próbuję wyciągnąć ostatnią kolumnę z File1i wydrukować ją sed 's/[{}//g' File1 > File3

Następnie kopiuję całą zawartość File1do nowejFile4

cp File1 File4

Potem zastąpić dane wewnątrz File4z File3danych (czyli danych bez jeden wspornik „ File1Ostatnia kolumna jeden”),

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

Wynik powinien być taki

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

Wreszcie próbuję

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

Ale wynik nie wyszedł tak, jak chcę, tylko podobne dane MNB są wymienione na liście, inne się nie pokazały (Plik danych z ostatniej kolumny),


Czy używasz GNU AWK?
123

nie jestem pewien, co masz na myśli. Ale jestem tylko nowicjuszem w dziedzinie dotykania awk. To jest zadanie, które muszę wykonać, staram się powoli, od kroku do kroku, robić to w oparciu o moje zrozumienie awk.
heng960407

1
typ awk --version, jaki jest wynik?
123

2
Zmień tytuł na coś bardziej specyficznego dla twojego problemu. Ułatwi to znalezienie go innym osobom, które mają podobne pytania. W tej chwili „Pytanie o awk” jest bardzo ogólne.
Tom Fenech,

Odpowiedzi:


16

Nie wiem, dlaczego kopiujesz rzeczy w lewo i prawo. Prosta rzecz jest

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

Umieszczam -początek i ;koniec.

W międzyczasie drukujemy

  • $2 ponieważ chcemy, aby tak było.
  • podciąg z $5 , który jest ciągiem bez pierwszego i ostatniego znaku. Pomijamy pierwszy znak, zaczynając od pozycji 2 (awk zawsze był w tym dziwny) i pomijamy ostatni znak, wybierając tylko podłańcuch, który jest o dwa znaki krótszy, niż oryginał$5
  • +ponieważ chcemy go
  • i wtedy $4

Nie jestem jednak pewien, czy wszystkie te funkcje łańcuchowe są specyficzne dla GNU awk.


substr(string, 2)zwraca podciąg począwszy od drugiego znaku, jak cut -c2-, tail -n +2, sed '2,$'... Co więc dziwnego?
Stéphane Chazelas,

3
To polecenie jest standardowe i działałoby nawet z oryginałem awkz lat 70.
Stéphane Chazelas,

@ StéphaneChazelas: Ach, czekałem na ciebie :-) Zazwyczaj zaczynamy od zera, co oznacza, że ​​indeks 2 jest trzecią pozycją, ale tutaj druga pozycja jest pod indeksem 2. Dziękujemy za wyjaśnienie pozostałego pytania GNU.
Bananguin

@Bananguin, w powłoce uniksowej i narzędziach, jak pokazano w kilku powyższych przykładach, zaczynamy od 1, a nie 0. Najbardziej znaczącymi wyjątkami są tablice ksh i $ {var: offset} (oba skopiowane przez bash). Wszystkie pozostałe tablice powłok zaczynają się od 1. Zobacz także Czy istnieje powód, dla którego pierwszy element tablicy Zsh jest indeksowany przez 1 zamiast 0?
Stéphane Chazelas

7

Z sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

I odmiana awk

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

Łatwa praca TXR :

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

Używanie makra awk TXR Lisp do transliteracji rozwiązania Awk:

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

Pola znajdują się na fliście, a indeksowanie opiera się na wartości zero.


1
+1 za seplenienie i najbardziej krystaliczny wygląd! Ten język MUSI współzawodniczyć w PCG (programowanie kodu golfa)
Archemar

@Archemar TXR nie konkuruje zbyt dobrze w golfie, ponieważ istnieją wyspecjalizowane języki zaprojektowane do tego celu, takie jak przypisywanie funkcji poszczególnym postaciom, które można następnie łączyć w celu uzyskania kompozycji.
Kaz.


1
@Kaz Czy jest gdzieś tutorial TXR? Strona podręcznika wydaje się dość duża. Jak to działa w porównaniu do awk?
bli

1
@bli GNU Awk jest co najmniej 30 razy szybszy przy podstawowym dzieleniu pól przez duży plik niż makro awk TXR, co stanowi ponad 220 linii interpretowanego kodu , w tym ogólną pętlę przetwarzania źródeł wejściowych na rekordy i pola.
Kaz

3

Korzystanie z awk jest najłatwiejsze, gdy $1,$2,...pola zawierają już dokładnie te ciągi, z którymi chcesz pracować. Separator pól, jeśli zawiera więcej niż jeden znak, jest interpretowany jako wyrażenie regularne. Nie musimy wykonywać żadnych operacji wyszukiwania i zastępowania ani podciągania, aby pozbyć się {nawiasów klamrowych}. Po prostu liczymy je jako część separatora.

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

Użycie printfzamiast zamiast printsprawia, że ​​trochę łatwiej jest zobaczyć, jak ciąg zostanie sformatowany, ale jeśli chcesz print "-"$2,$5" + "$4";"zamiast tego printf("-%s %s + %s ;\n", $2, $5, $4), jest to opcja.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.