trはどのようにして1つの単語を別の単語に翻訳しますか?


9

ファイルがma.txtあり、その出力が含まれていますls -ltrコマンド(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

1行目で「nik」が「too」に置き換えられ、「Desktop」のスペルが「Desottt」になりました。

どうしてこれなの?その背後にあるロジックは何ですか?


3
info coreutils 'tr invocation'trができるのか詳細を教えてくれます。
ネフェンテ2016年

4
ところであなたは何をしようとしていますか?コマンドは、あなたがそれをやるように言われ、正確に何をしたが、私はあなたが実際に交換したいと思いますnik-pcroot
コス2016年

3
最初のステップは、常にコマンドのmanページを確認することです。
モスタファアハンガラ2016年

1
@DavidZ:これnk-p範囲内であることに注意してください。文字が最初のセットに複数回現れる結果は、POSIXでは規定されていません。
hmakholmがモニカを去った

1
私はあなたが本当に必要なのはsedコマンドだls -l | sed 's/nik-pc/root/'と思います... あなたが望むことをするでしょう。 tr単一の文字を変換するためのもの-例 小文字から大文字、またはdosスタイルのラインシフト(\ r)からUnixスタイル(\ n)、またはすべてのバックスラッシュ(Windows)をスラッシュに置き換えるようなもの。また、「不要な」文字を削除することもできます。すべて数字またはすべて大文字。
Baard Kopperud 2016年

回答:


16

tr文字列を文字単位に変換します。最初のセットの文字を検索し、それらを2番目のセットの文字で置き換えます。

あなたはnik-pc最初のセットとして持っていました。trそのk-p部分を「k」から「p」までの範囲のすべての文字に展開するため、セットはに等しくなりniklmnopcます。

2番目のセットはでしたroot

tr今行うことは(評価される)最初のセットの最初の文字のすべての出現箇所を検索し、第二セットの最初の文字に置き換えることです。セット2に文字がなくなると、単に最後の文字を繰り返します。下の表を参照してください。

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

これで、「デスクトップ」が「デスクトップ」になる理由が明らかになりました。動作は完全に正しく、このように意図されています。


代わりにあなたが探しているものは、以下を使用して達成できます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'
Sergiy Kolodyazhnyy 2016年

18

tr完全な単語ではなく、文字を翻訳するためのものです。セットを翻訳できます。あなたの例では、最初のコレクション文字として「nik-pc」があり、「root」は別のものです。実際には、k-pは範囲なので、kからpまでのすべての文字が含まれます。charを1つずつ照合するため、nはr、iはo、kはoに変換され、4番目の文字を超えるものはすべてtになります。そのため、「デスクトップ」を「デスクトップ」に翻訳しました

この例でそれをよりはっきりと見ることができます:

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

ここで見ることができます tr セット1の位置4にD、セット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 s / nik-pc / root / g ma.txt> ma2.txt
Bruni

1
あなたは私よりもはるかに高速だった@Serg ...:P
バイトコマンダー

2
@ByteCommander私はスピードで勝ったかもしれませんが、あなたの答えは品質で勝つと思います
セルギーコロディアズニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.