1. 程式人生 > 其它 >shell中文字處理的基本方式

shell中文字處理的基本方式

2021-06-14

關鍵字:


1、echo

echo是shell中最常用的文字輸出命令。其基本語法如下所示:

echo [option] string...

echo命令可用的 option 如下表所示:

option 釋義
-E 預設選項,當echo不攜帶任何選項時即相當於帶上了此選項。此選項表示不解析string中的轉義字元。
-e 與 -E 相對,使用此選項後即表示會解析string中的轉義字元。
-n 在輸出完string後不追加一個換行字元。

另外,echo命令支援的轉義字元如下表示所:

轉義字元 含義
\a 報警符。相當於ASCII中的BEL字元。
\b 退格符。輸出此轉義字元會將已輸出的一個字元“吃掉”。
\c 禁止繼續輸出文字。輸出此轉義字元後,同一條echo命令後面要輸出的文字均不會再執行。
\f 換頁符
\n 換行符
\r 回車符
\t 水平製表符
\v 垂直製表符
\\ 輸出一個反斜線

echo 命令預設將文字輸出到控制檯,即作為列印資訊顯示在螢幕上。可以使用重定向符將文字流往檔案系統輸出。具體如下所示:

#!/bin/bash

#將文字儲存到 /var/file1 檔案中去
echo "hello world" > /var/file1

#將文字追加到 /var/file1 檔案中去
echo
"hello rust" >> /var/file1

下面結合echo命令的選項及轉義字元編寫一個 0% ~ 100% 的進度條顯示shell函式。該函式不同於傳統的echo輸出命令會為每一個新值開闢一個新行,而是在數值更新時直接將舊值更新為新值。就類似於日常手機或網頁中的百分比進度條那種效果。這個shell函式的核心思想就是使用 \b 退格轉義字元,在百分比值更新時將已輸出在螢幕上的舊值“吃掉”,然後再填充以新值從而達到我們想要的效果。

以下是完整的原始碼:

#!/bin/bash

#定義列印百分比值的函式
function progress ()
{
    #引數檢查,呼叫此函式時必須傳遞一個引數
    
if [ $# -ne 1 ]; then echo "Usage:" echo " progress [percentage]" echo "eg:" echo " progress 0" echo " progress 100" return 1 fi #引數型別檢查,傳遞進來的引數必須是 0 ~ 100 之間的整數 local progress_ttmp_1=1 if [ $1 -ge 0 2> /dev/null -a $1 -le 100 2> /dev/null ]; then progress_ttmp_1=0 fi if [ $progress_ttmp_1 -ne 0 ]; then echo "Can only accept integer parameter" return 2 fi #百分比值更新。progress_ttmp_2 變數純粹是為了標識是否第一次呼叫此函式。這關係到如何輸出\b字元 if [ "$progress_ttmp_2" = "1" ]; then #控制好\b字元的輸出數量從而保證輸出格式不出錯。 if [ $1 -le 10 ]; then echo -ne "\b\b$1%" else echo -ne "\b\b\b$1%" fi else progress_ttmp_2="1" #首次呼叫函式,無須輸出\b轉義字元 echo -n "$1%" fi } #模擬一個從 0 ~ 100 的進度狀態流程 for (( i=0; i<101; i++ )) do progress $i #當函式成功執行時延時10毫秒來模擬後臺作業耗時 if [ $? -eq 0 ]; then sleep 0.01 else #進度打印出錯時直接退出 break fi done

2、fold

fold命令的功能是將超過指定寬度的文字行強制做換行處理。其語法如下所示:

fold [option] [file]...

fold 命令可以同時處理多個檔案,不同檔案之間以空格字元隔開。

option的可選值如下表所示:

選項 含義
-b 按位元組計算寬度。超過-w選項指定的位元組數時為此行做換行處理。預設情況下按列數計算(按字元)。
-s 在空格處做換行操作以避免單詞被折斷。
-w 指定行寬度上限。超過此選項指定的寬度值時自動為此行做換行處理。預設的寬度是80列後換行。

具體的使用示例如下所示:

fold -w 55 story.txt
fold -s -w 86 story.txt
fold -b story.txt
fold -b -w 100 story.txt

3、fmt

與fold命令類似,fmt命令的功能也是將超過指定寬度的文字行強制換行。但是fmt的功能會多於fold命令。其語法如下所示:

fmt [-width] [option] [file]

-width引數用於指定文字行的列數,預設為75列,即75個字元後換行。

此命令同樣可以同時處理多個檔案,不同檔案之間以空格隔開。

option的可選值如下表所示:

選項 含義
-c 保留每個段落的前兩行的縮排。
-t 與-c選項功能類似,但是在使用此選項時,每個段落的第1行和第2行的縮排必須是不相同的,否則第1行被看做一個單獨的段落。
-s 只折斷超出指定寬度的行,不合並少於指定寬度的行。預設情況下是會合並少於指定寬度的行的。
-u 統一空格數量,單詞之間保留1個空格,句子之間保留2個空格。
-w 指定每個行的最大寬度,預設為75列。

以下是具體的示例程式:

fmt -c -w 80 story.txt
fmt -s -c -w 80 story.txt
fmt -20 -s story.txt

4、rev

rev命令的作用是反轉字元順序。即將文字中每一行的字元倒轉過來。語法如下所示:

rev [file]...

多個檔案之間以空格字元隔開。

使用示例如下所示:

rev story.txt

5、文字統計

1、輸出帶有行號的文字

可以使用 cat 命令帶引數,如下所示:

cat -n story.txt

將輸出的流重定向至檔案中即可完成格式化修改。

除此之外,nl 命令也可為檔案流帶上行號。其語法如下所示:

nl [option] [file]

nl命令支援的option較多,常用的幾個則如下表所示:

option 含義
-b 顯示風格控制。可取 a , t , n 作為值。a表示為所有行新增行號。t表示僅為非空行新增行號(預設)。n表示不新增行號。
-i 行號的增量,預設為1。
-v 行號的起始值,預設為1。

使用示例如下所示:

nl story.txt
nl -b a story.txt

2、統計行數

使用 grep 命令加 -c 選項可以統計符合條件的結果行數。其示例程式碼如下:

grep -c "keyword" story.txt

另外,還有一個更專業的統計文字專用的命令:wc。

wc命令即 word count 的縮寫。其語法如下所示:

wc [option] [file]

option可用的值如下表所示:

option 含義
-c 統計文字的位元組數。
-m 統計字元數。
-l 統計行數。
-L 統計最長的文字行的長度。
-w 統計單詞數。

具體示例如下所示:

wc -m story.txt
wc -l story.txt

直接使用wc命令統計檔案中文字的資料時會在統計結果末尾顯示出被統計檔名。如果不想顯示此檔名,可以配合cat和管線命令來去除,具體用法如下所示:

cat story.txt | wc -m
cat story.txt | wc -l

6、cut

cut命令的作用是將文字中的資料按指定分隔符提取若干文字列。其語法如下所示:

cat [option] [file]

常用的option值如下表所示:

option 含義
-b 只選擇指定的位元組。
-c 只選擇指定的字元。
-d 自定義列分隔符,預設為製表符。
-f 只選擇列表中指定的文字列。文字列號從1開始,多個列之間以逗號隔開,連續列以減號代替。
-n 取消分隔多位元組字元
-s 不輸出不包含列分隔符的行。

具體示例如下所示:

cut -d ":" -f 1,7 /etc/passwd

表示將 /etc/passwd 檔案以 ":" 作為分隔符,提取其第1列與第7列的資料。

cut -d ":" -f 1-4 /etc/passwd

功能同上,這次提取的是第1 ~ 第4列的資料。

cut -d ":" -f 3- /etc/passwd

功能同上,這次提取的是第3列及以後的資料。

cut -d ":" -f 1,2,4-7 /etc/passwd

功能類似於上面幾條。

可以不指定分隔符只提取文字中指定列號處的字元資料:

cut -c 1,3,5 /etc/passwd

7、paste

paste命令與cut命令是相對的一組命令,它負責將多個檔案中的內容合併起來。其語法如下所示:

paste [option] [file]

option常用的值如下表所示:

option 含義
-d 指定拼接結果中列分隔符。預設使用製表符分隔。
-s 將多個檔案序列拼接,即後面的檔案內容以追加的方式新增到前一個檔案內容中。

具體示例如下所示:

paste story.txt author.txt > book_info.txt

paste命令本身不支援選列拼接,但是可以通過與cut命令配合來達到此效果,示例如下:

cut -f 1,2 phones.txt > phones.tmp
cut -f 2 authors.txt > authores.tmp
paste authores.tmp phones.tmp > contacts.txt

8、tr

tr 命令是 translate 的縮寫。其功能是批量替換文字中的字元。語法如下:

tr [option] [set1] [set2]

option常用的值如下表所示:

option 含義
-c 用字符集set2替換字符集set1中沒有包含的字元。
-d 刪除字符集set1中的所有字元,不執行替換操作。此時無須傳入set2引數。
-s 壓縮set1中重複的字元。
-t 將字符集set1用set2轉換。

如想去掉文字中所有的空行:

cat story.txt | tr -s ["\n"]

刪除指定字元:

tr -d [rust] < story.txt

此舉,會將 story.txt 中所有的字母 r , u , s, t 刪除掉。

個人認為,tr命令特別不實用。