Як тр перекладає одне слово на інше?


9

У мене є файл, ma.txtі він містить вихід ls -l; коли я запускаю trкоманду ( tr "nik-pc" "root"), я отримую цей вихід:

nik-pc@nik:~$ cat ma.txt 
total 52
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 11:33 Desktop
lrwxrwxrwx 1 nik-pc nik-pc    2 Mar  8 22:54 di -> hd
drwxr-xr-x 3 nik-pc nik-pc 4096 Mar 13 13:28 Documents
drwxr-xr-x 7 nik-pc nik-pc 4096 Mar 14 18:21 Downloads
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 09:39 dwhelper
-rw-r--r-- 1 nik-pc nik-pc 2134 Mar 13 17:40 hd
-rw-r--r-- 1 nik-pc nik-pc    3 Mar 13 15:34 m
-rw-r--r-- 1 nik-pc nik-pc    0 Mar 17 19:48 ma.txt
drwxr-xr-x 3 nik-pc nik-pc 4096 Mar 13 14:58 Music
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 12:30 Pictures
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Public
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 13 15:58 sd
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Templates
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar  5 11:44 Videos
drwxr-xr-x 2 nik-pc nik-pc 4096 Mar 11 11:33 xdm-helper

nik-pc@nik:~$ tr "nik-pc" "root" < ma.txt 
tttat 52
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 11:33 Desottt
trwxrwxrwx 1 too-tt too-tt    2 Mar  8 22:54 do -> hd
drwxr-xr-x 3 too-tt too-tt 4096 Mar 13 13:28 Dttutetts
drwxr-xr-x 7 too-tt too-tt 4096 Mar 14 18:21 Dtwtttads
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 09:39 dwhetter
-rw-r--r-- 1 too-tt too-tt 2134 Mar 13 17:40 hd
-rw-r--r-- 1 too-tt too-tt    3 Mar 13 15:34 t
-rw-r--r-- 1 too-tt too-tt    0 Mar 17 19:48 ta.txt
drwxr-xr-x 3 too-tt too-tt 4096 Mar 13 14:58 Musot
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 12:30 Pottures
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Pubtot
drwxr-xr-x 2 too-tt too-tt 4096 Mar 13 15:58 sd
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Tetttates
drwxr-xr-x 2 too-tt too-tt 4096 Mar  5 11:44 Vodets
drwxr-xr-x 2 too-tt too-tt 4096 Mar 11 11:33 xdt-hetter

На першому рядку він замінив "nik" на "занадто", а правопис "Desktop" став "Desottt".

Чому це? Яка логіка за цим?


3
info coreutils 'tr invocation'розповідає детально, що trробить.
Нефенте

4
Що ви намагаєтеся зробити до речі? Команда зробила саме те , що ви сказали це зробити, але я припускаю , що ви на справді хочете , щоб замінити nik-pcз root?
kos

3
Перший крок - це завжди перевірити головну сторінку команди.
Мостафа Ахангарха

1
@DavidZ: Зауважте, що nце також в k-pдіапазоні. Результат символу, який з’являється більше одного разу на першому наборі, не визначений POSIX.
hmakholm виїхав над Моніку

1
Я думаю, що вам справді потрібно, це sedкоманда ... ls -l | sed 's/nik-pc/root/'зробить те, що ви хочете. trпризначений для перетворення одиночних символів - наприклад. нижній регістр на верхній регістр, або перехід ліній в стилі dos (\ r) на стиль Unix (\ n), або щось на зразок заміни косої косої риски (Windows) на косу рису. Він також може видаляти "небажані" символи, наприклад. всі цифри або великі літери.
Баард Копперуд

Відповіді:


16

trперекладає строковий символ. Він здійснює пошук літер з першого набору і замінює їх тими, які формують другий набір.

У вас був nik-pcяк перший сет. trрозширює цю k-pчастину на всі літери в діапазоні від "k" до "p", тому множина дорівнює niklmnopc.

Ваш другий набір був root.

Що trтепер робить це шукати все входження першого символу в (оціненого) першому наборі і замінити їх з першим символом другого набору. Коли в наборі 2 немає більше символів, він просто повторює останній символ. Дивіться таблицю нижче:

n --> r
i --> o
k --> o
l --> t
m --> t
n --> t
o --> t
p --> t
c --> t

Тож тепер зрозуміло, чому, наприклад, "Desktop" стає "Desottt". Поведінка повністю коректна і призначена таким чином.


Що ви шукаєте натомість, можна досягти, використовуючи sed:

sed 's/nik-pc/root/g' ma.txt

Синтаксис такий:

sed 's/SEARCH_PATTERN/REPLACE_STRING/FLAGS' INPUT_FILE

Тож ми дозволяємо йому шукати шаблон "nik-pc" і заміняємо весь збіг на "root". Нам потрібно додати прапор "g", щоб дозволити глобальну заміну. Без цього він би заміняв лише кожен перший матч за рядком.


Ця таблиця зі стрілками робить пояснення ще зрозумілішим, мені це подобається. + 1-вид. Користувач міг би зробити щось подібне зprintf "A\nB\nC\n" | tr 'ABC' '12'
Сергій Колодяжний

18

trпризначений для перекладу символів, а не для повних слів. Він може перекладати набори. У вашому прикладі у вас є "nik-pc" як перші символи колекції, а "root" - інший. Насправді k-pце діапазон, тому він включає всі символи від k до p. Він буде відповідати символам один за одним, тому n буде переводити на r, i в o, k до o, і все, що більше, ніж 4-е символи, буде t. Ось чому у вас "Desktop" перекладено на "Desottt"

Ви можете зрозуміти це на цьому прикладі:

$ echo "ABCDEF" | tr "ABCDEF"  "12"                            
122222

Тут ви можете бачити, що tr множина 1 має D у положенні 4. Але множина 2 не має позиції 4, тому для перекладу буде використана остання множина 2.

Що ви робите, це перекладати одне слово на інше. Що ви хочете зробити, це використовувати більш просунутий інструмент, як sedабо awk.

Наприклад,

$ ls -l /etc/passwd | awk '{gsub(/root/,"TEST");print}'        
-rw-r--r-- 1 TEST TEST 2575 Feb 29 12:30 /etc/passwd

6
АБО sed sed s / nik-pc / root / g ma.txt> ma2.txt
Бруні

1
Ти був набагато швидшим за мене @Serg ...: P
Байт командир

2
@ByteCommander Я, можливо, переміг у швидкості, але думаю, що ваша відповідь перемагає в якості
Сергій Колодяжний,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.