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命令特別不實用。