Jak działają opcje „-s”, „-t” i „-c” polecenia tr w systemie Unix?

12

Nie mam jasności co do sposobu -s, -toraz -cmożliwości pracy w tr polecenia. Kiedy robię

echo I am a good boy | tr good bad

Otrzymuję wynik:

I am a bddd bdy

Jest to całkiem zrozumiałe, ponieważ opowtarza się w good. Ostatnią możliwą zmianą w miejsce ojest d, a stąd wynik.

Teraz kiedy to zrobię

echo I am a good boy | tr -s good bad

wyjście jest

I am a bd bdy

-sOpcja ma wycisnąć powtarzającego wystąpienie każdego znaku w zestawie 1 do jednego wystąpienia i następnie zmienić każdy znak w zestawie 1 do odpowiedniego znaku w zestawie 2, który jest w tej samej pozycji.

Tak powinno być

I am a bad bay.

Skąd ta zmiana?

Co więcej, kiedy to zrobię

echo I am a good boy | tr -c good bad

dostaję dddddddgoodddodd

Jak działa -copcja w trodniesieniu do tego przykładu?

I wreszcie: jak zmienić się z dobrego chłopca w złego chłopca .... :): P To znaczy,

echo I am a good boy | tr <something>Daje mi wyjście jak: I am a bad boy.

dig_123
źródło

Odpowiedzi:

12

-s Switch: Squeeze (usuń powtarzające się postacie)

echo i am a good boy | tr -s good bad

wynik: i am a bd bdy

Za kulisami dzieją się dwie rzeczy. Po pierwsze, jeśli drugi argument do trjest krótszy niż pierwszy, to powtarzany jest ostatni znak w drugim arg, aby uzyskać taką samą długość jak pierwszy. Więc równoważne polecenie to:

echo i am a good boy | tr -s good badd

Inną rzeczą, która się dzieje jest to, że znaki w pierwszym argumencie są powtarzane, zastępują one każde poprzednie wystąpienie (mam na myśli dwie litery oos good). Dzięki temu polecenie jest teraz równoważne z:

echo i am a good boy | tr -s god bdd

(drugi odo dwymiany nadpisuje poprzedni odo awymiany, dzięki czemu jest redundantny)

Bez -sprzełącznika wyjście byłoby

i am a bddd bdy

Za pomocą -sprzełącznika tr„ściska” wszystkie powtarzające się znaki, które są wymienione w ostatnim argumencie, pozostawiając końcowy wynik:

i am a bd bdy

-c Przełącznik: Uzupełnienie

-cPrzełącznik służy do dopasowywania dopełnienie pierwszego argumentu (czyli wszystkich znaków nie wymienionych w arg 1). W rezultacie arg 1 będzie zawierać wiele liter (256-3). To samo dzieje się z arg 2, jak w poprzednim przypadku: końcowy znak Arg 2 powtarza się, aby dopasować długość lub Arg 1. Tak więc oryginalne zdanie:

echo i am a good boy | tr -c good bad

jest równa:

echo i am a good boy | tr abcefhijklmnp... baddddddddddd...

(zwróć uwagę na brakujący g, oaw dpierwszym zestawie również zwróć uwagę, że dzastąpi on co drugi znak w drugim zestawie - w tym znak spacji)

Właśnie dlatego i am a good boyzamienia się wdddddddgoodddodd

Więcej informacji tutaj: http://www.linuxjournal.com/article/2563

ltn100
źródło
Zasadniczo poprawne, z wyjątkiem tego, że -sprzełącznik powoduje trwyciskanie dowolnych znaków z ostatniego argumentu na tr(nie pierwszy, jak mówisz), które są powtarzane na wejściu. Jest to zauważono w artykule ty związane i wyjaśnione w ostatnim akapicie, w sekcji „Opis” na stronie man .
ravron
4

Twoje zrozumienie -sjest nieprawidłowe, zastępuje powtarzające się występowanie znaków w zestawie 1 na wejściu pojedynczym znakiem. nie modyfikuje zestawu, np.

echo i am a good boy | tr -s god bad

daje

i am a bad bay

Do -czastępuje opcja ustaw 1 z dopełnieniem (tj. Zbiór wszystkich znaków nie zawarte w zestawie 1). Możesz go użyć do usunięcia na przykład wszystkich znaków oprócz określonych.

echo i am a good boy | tr -cd gobdy

wyjścia

goodboy
Hasturkun
źródło
: Mam twój punkt widzenia na opcję -s, ale moje pytanie brzmi: jak: echo jestem dobrym chłopcem | tr -s good bad daje wynik, ponieważ: jestem bd bdy jest to możliwe tylko wtedy, gdy tak się dzieje: najpierw jestem dobrym chłopcem, zmieniam się na bddd bdy, a następnie opcja -s zmienia występowanie wielokrotności d na single tj .: jestem bddd bdy, a następnie zmienia się na jestem bd bd, czy to właśnie się dzieje? proszę, rozbij to dla mnie, to samo z opcją -c jak echo jestem dobrym chłopcem | tr -cd gobdy podając to: goodboy
1

Pozostałe odpowiedzi pokryte tr„s -s, -ti -copcje, ale dla kompletności:

Masz problem, ponieważ wybrałeś niewłaściwe narzędzie.

  • tr służy do transformacji postaci
  • sed służy do edycji strumieniowej.

Ponieważ oba goodi badsą ciągiem znaków w strumieniu sedjest lepsze dopasowanie.

echo I am a good boy | <something> daje mi wynik jako: I am a bad boy

$ echo I am a good boy | sed s/good/bad/g
I am a bad boy

s/..../..../Jest Zastępca. Cokolwiek pasuje do pierwszego wyrażenia regularnego, zostanie zastąpione drugim. /gFlagi na końcu jest do wymiany Globalnego ten sposób wszystkie wystąpienia zostaną zastąpione nie tylko pierwszy.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/
I am a bad boy and a good boy is me.

$ echo I am a good boy and a good boy is me. | sed s/good/bad/g
I am a bad boy and a bad boy is me.
Aaron Goldman
źródło
0

tak. dokładnie!

tr -s zastępuje wystąpienia powtarzających się znaków jednym znakiem.

(przez stronę manuala).

wygląda to tak:

przekształca goodsię w bddd. powtarzające się wystąpienia to 3 'd.

więc zastępuje te trzy wystąpienia pojedynczym wystąpieniem.

to znaczy, że to bd. :)

Rahul Mishra
źródło
2
Nie oczekujemy, że każda odpowiedź będzie idealna, ale odpowiedzi z poprawną pisownią, interpunkcją i gramatyką są łatwiejsze do odczytania.
Ashildr,