2013-11-29

Ubuntu 用 tr 指令快速取代字元和移除換行符號

阿舍在還沒認識這個 tr 指令之前,都是用 vi 或是 sed 來更改檔案裡的字串的,不過,vi 和 sed 的字串取代都是透過正則表示式 ( Regular Expression ) 來處理的,雖然,正則表示式在處理複雜的取代時,會很好用,但是,如果只是簡單取代的話,阿舍就覺得有點不是那麼直覺哩 ! 而阿舍今天要講的這個 tr 指令,在簡單的字串取代的操作上,就會直覺和簡單不少哩 !

tr 指令範例

大概有不少阿舍一樣,接觸到 tr 指令的第一個機會,就是需要把檔案裡的每一行的換行符號給換掉的情況吧 ! 阿舍是手上有一個檔案被用換行符號給切成很多行了,阿舍想把它合併回來的話,這個時候,就可以用 tr 指令來處理一下,只要用下面這一行指令就可來搞定了哩 !

tr "\n\r" "," < arthurtoday.txt  > arthurtoday_out.txt

以上面的這行指令為例來說,阿舍用「<」符號餵給 tr 指令一個叫做「arthurtoday.txt」的檔案,然後,給 tr 指令的第一個參數的「\n\r」是要被換掉的字串,而第二個的「,」符號則是阿舍要置換成的字串,最後,再加上「>」符號來把 tr 指令處理過的資料給存到「arthurtoday_out.txt」檔案,這樣,阿舍就可以很快的把 arthurtoday.txt 檔案裡,不管有多少個換行號,都一次把它換成逗號哩 ! 這樣有沒有很快速哩 !

要注意的有幾點,一個是關於換行符號的部分,如果是 Windows 來的檔案,那麼是用 \n\r 來代表,但是,如果是 Ubuntu 或 Linux 產的檔案的換行符號的話,就只要用 \n 就可以了,另外,就 tr 指令產出的部分,如果沒有用 「>」或「|」符號來把 tr 指令產出的結果存到檔案或交給其它程式處理的話,tr 指令就只會把結果顯示在螢幕上,這樣的話,似乎就沒有太大的用途哩 !

另外,如果不習慣用「<」符號來把檔案交給 tr 指令處理的話,也可以用下面這一行的方式,就是利用 cat 指令和「|」符號來把檔案內容傳給 tr 指令來處理哩 !

cat arthurtoday.txt | tr "\n\r" " " > arthurtoday_out.txt

還有,阿舍的例子是把換行符號換成逗號,但是,如果是要把換行號移掉的話,那要怎麼辦呢 ?  請不要和阿舍一樣單純,想用下面第一行的方式來移除,也就想要給 tr 指令一個空字串,然後,請它把換行符號換成空字串,這是不行的,因為,tr 指令是不會接受空字串來當做置換的目的字串的哩 !

cat arthurtoday.txt | tr "\n\r" "" > arthurtoday_out.txt

要把字串換成空字串,其實就是要刪除的意思吧 !  所以,如果是要刪除某個字串的話,就要用到 tr 指令的「d」選項哩 ! 因此,以上面提到要刪除換行符號的例子來說,操作指令應該是要下面這個樣子才對哩 ! ( 那可以給空字串來換成任何字元嗎 ? 當然可以,不過 ... tr 就會變作 cat 了哩 ! ... 請問在檔案裡是那裡可以找到空字元哩 ?? .... = = !! ... 呵 !)

cat arthurtoday.txt | tr -d "\n\r"  > arthurtoday_out.txt

( 阿舍介紹的 Ubuntu 指令,只要是標籤 ( Tag ) 有標上 Linux 或 Android 的話,就表示阿舍介紹的指令可用在大部份的 Linux 發行版本及 Android 手機上 (需安裝終端機 APP ),只是,阿舍都只有在 Ubuntu 上測試過而已哩 !  .... ^^= )

推薦閱讀


有疑問? 問題還是沒解決嗎? 歡迎下方留言提問和討論 😁

1 則留言 :

艾德華 提到...

從您的文章獲益良多,非常謝謝!請教一下,從man page裡面看到,在「tr 字串一 字串二」的語法中,是會依序把[字串一的第一個字元]代換成[字串二的第一個字元],然後[字串一的第二個字元]代換成[字串二的第二個字元],這樣依此類推。如果字串一比字串二來得長,那麼將會重複使用字串二的最後一個字元,直到把字串一內的字元逐一用完為止。

如此一來,「tr "\n\r" ","」照理說會分別把「\n」和「\r」都代換成逗號,而造成重複兩次逗號才對。為什麼沒有這樣發生呢?難道「\n\r」是被視為單一個字元,而非兩個字元嗎?

張貼留言

歡迎留言提問和討論 .... 😁