Mam plik, który wygląda tak:
AE United Arab Emirates
AG Antigua & Barbuda
AN Netherlands Antilles
AS American Samoa
BA Bosnia and Herzegovina
BF Burkina Faso
BN Brunei Darussalam
Chciałbym odwrócić kolejność, drukując najpierw wszystko oprócz 1 $, a potem 1 $:
United Arab Emirates AE
Jak mogę zrobić sztuczkę „wszystko oprócz pola 1”?
Odpowiedzi:
Przypisanie
$1
działa, ale pozostawi spację wiodącą:awk '{first = $1; $1 = ""; print $0, first; }'
Możesz także znaleźć liczbę kolumn
NF
i użyć jej w pętli.źródło
awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'
$1=""
pozostawia miejsce, o czym wspomniał Ben Jackson, więc użyjfor
pętli:Więc jeśli twój ciąg to „jeden, dwa, trzy”, wynik będzie taki:
dwa
trzy
Jeśli chcesz, aby wynik był w jednym wierszu, możesz wykonać następujące czynności:
To da ci: „dwa, trzy”
źródło
awk '{for(i=2;i<=NF;i++){ printf("%s",( (i>2) ? OFS : "" ) $i) } ; print ;}'
co: drukuje pola 2 do NF, dodaje separator pól wyjściowych w razie potrzeby (tj. z wyjątkiem przed $ 2). Ostatni wydruk dodaje ostatnią nową linię, aby zakończyć drukowanie bieżącej linii. Ten zadziała, jeśli zmienisz FS / OFS (tj. Nie zawsze będzie to „spacja”)Użyj
cut
polecenia z--complement
opcją:źródło
echo a b c | cut -d' ' -f 2-
jest alternatywąMoże najbardziej zwięzły sposób:
Wyjaśnienie:
$(NF+1)=$1
: Generator „nowego” ostatniego pola.$1=""
: Ustaw pierwotne pierwsze pole na wartość nullsub(FS,"")
: Po pierwszych dwóch akcjach{$(NF+1)=$1;$1=""}
pozbądź się pierwszego separatora pól za pomocą sub. Ostateczny wydruk jest niejawny.źródło
Usuń pierwsze pole i separator, a następnie wydrukuj wynik (
7
jest to wartość różna od zera, więc wypisuje się $ 0).źródło
1
? Zastanawiam się nad zastosowaniem tego wzoru i chciałem to zrozumieć. dzięki!Ustawienie pierwszego pola na
""
pozostawienie pojedynczej kopiiOFS
na początku$0
. Zakładając, żeOFS
jest to tylko jeden znak (domyślnie jest to pojedyncza spacja), możemy go usunąć za pomocąsubstr($0, 2)
. Następnie dołączamy zapisaną kopię pliku$1
.źródło
Jeśli jesteś otwarty na rozwiązanie Perla ...
to proste rozwiązanie z separatorem wejścia / wyjścia jednej spacji, które daje:
Ten następny jest nieco bardziej złożony
i zakłada, że separatorem wejścia / wyjścia są dwie spacje:
Używane są następujące opcje wiersza polecenia:
-n
pętla wokół każdego wiersza pliku wejściowego, nie drukuj automatycznie każdego wiersza-l
usuwa nowe wiersze przed przetworzeniem i dodaje je później-a
tryb autosplit - dzieli linie wejściowe na tablicę @F. Domyślnie dzielenie na białe znaki-F
modyfikator autosplit, w tym przykładzie dzieli się na „” (dwie spacje)-e
wykonaj następujący kod Perla@F
to tablica słów w każdym wierszu indeksowana od 0$#F
to liczba słów w@F
@F[1..$#F]
tablicy kawałek od elementu 1 do ostatniego elementu@F[1..$#F,0]
to tablica od elementu od 1 do ostatniego elementu plus element 0źródło
Separatorem pól w gawk (przynajmniej) może być zarówno łańcuch, jak i znak (może to być również wyrażenie regularne). Jeśli Twoje dane są spójne, to zadziała:
To dwie spacje między podwójnymi cudzysłowami.
źródło
awk '{ tmp = $1; sub(/^[^ ]+ +/, ""); print $0, tmp }'
źródło
Przenieśmy wszystkie rekordy do następnego i ustawmy ostatni jako pierwszy:
Wyjaśnienie
a=$1
zapisz pierwszą wartość w zmiennej tymczasowej.for (i=2; i<=NF; i++) $(i-1)=$i
zapisz wartość N-tego pola w (N-1)-tym polu.$NF=a
zapisz pierwszą wartość ($1
) w ostatnim polu.{}1
prawdziwy warunek, abyawk
wykonać domyślną akcję:{print $0}
.W ten sposób, jeśli masz inny separator pól, wynik jest również dobry:
źródło
Pierwsza próba wydaje się działać w twoim konkretnym przypadku.
źródło
opcja 1
Istnieje rozwiązanie, które działa z niektórymi wersjami awk:
Wyjaśnienie:
Wynik:
Jednak może się to nie powieść w przypadku starszych wersji awk.
Opcja 2
To jest:
Zwróć uwagę, że to, co należy usunąć, to OFS, a nie FS. Linia jest obliczana ponownie, gdy pole $ 1 jest przypisane. To zmienia wszystkie przebiegi FS na jeden OFS.
Ale nawet ta opcja nadal zawodzi z kilkoma ogranicznikami, co wyraźnie widać po zmianie OFS:
Ta linia wyświetli:
To pokazuje, że przebiegi FS są zmieniane na jeden OFS.
Jedynym sposobem uniknięcia tego jest uniknięcie ponownego obliczania pola.
Jedną z funkcji, która pozwala uniknąć ponownego obliczania, jest sub.
Pierwsze pole może zostać przechwycone, następnie usunięte z 0 za pomocą sub, a następnie oba ponownie wydrukowane.
Opcja 3
Nawet jeśli zmienimy FS, OFS i / lub dodamy więcej ograniczników, to działa.
Jeśli plik wejściowy zostanie zmieniony na:
A polecenie zmienia się na:
Wynik będzie (nadal zachowując ograniczniki):
Polecenie można rozszerzyć do kilku pól, ale tylko z nowoczesnymi awksami i aktywną opcją --re-interval. To polecenie w oryginalnym pliku:
Wyświetli to:
źródło
Jeśli jesteś otwarty na inne rozwiązanie Perla:
źródło
Jest też opcja sed ...
Wyjaśnione...
Dokładniej wyjaśnione ...
źródło
Jeszcze inny sposób ...
... to łączy pola od 2 do NF z FS i wyprowadza jedną linię na linię wejścia
Używam tego z gitem, aby zobaczyć, jakie pliki zostały zmodyfikowane w moim katalogu roboczym:
źródło
Kolejny i łatwy sposób za pomocą polecenia cat
źródło