Shell編程從入門到精通——基本文本處理(一)

在Shell編程中用來做文本處理的命令有很多,第一部分,向大家介紹echo、文本的格式化輸出希望對你有幫助。

一、使用echo輸出文本行

在Shell中使用echo命令輸出文本是非常多見的,下面是echo命令的使用語法:
echo [options] string...
在上面的語法中,options表示命令選項,echo常用的命令選項比較少,如下:

  • -n  不在最後自動換行
  • -e  使用反斜槓的解釋
  • -E  抑制反斜槓的解釋

1.顯示普通字符

下面演示如何使用echo命令輸出用戶提示信息:

#! /usr/bin/env bash

echo -n "What is your first name?"
read first
echo -n "What is your last name?"
read last 

2.顯示轉義字符

echo命令可以控制輸出格式,下表列出了echo命令支持的轉義字符:

字符 說明
\a 報警符,相當於ASCII碼的 BEL字符
\b 退格符
\c 禁止繼續輸出文本
\f 換頁符
\n 換行符
\r 回車符
\t 水平製表符
\v 垂直製表符
\\ 反斜線

需要注意的是使echo命令支持轉義字符,還必須使用-e參數。
下面我們使用\c來禁止繼續輸出字符:

#! /usr/bin/env bash

echo -e "What is your first name? \c"
read first
echo -e "What is your last name? \c"
read last 

Output:

$ sh test.sh
What is your first name? random
What is your last name? wz

我們可以看到\c字符讓echo命令後面的換行並沒有執行。

3.顯示變量

用戶可以使用echo命令將程序中的變量值打印出來。

#! /usr/bin/env bash

echo -e "What is your first name? \c"
read first
echo "Hello $first"
#爲了使Shell能正確解析變量名,儘量用花括號將變量括起來
echo -e "What is your last name? \c"
read last
echo "Hello ${last} ${first}"

注意:變量名與不能作爲變量名的字符,例如-、’、及/等連接的時候,可以不使用花括號。

4.換行與不換行

在默認情況下,echo命令會在文本的最後輸出一個換行符,我們可以使用-n參數讓echo禁止輸出換行,當然也可以只用-e字符轉義\c,禁止輸出換行。

5.顯示命令執行結果

要顯示命令執行結果,我們需要使用反引號將命令括起來:

echo `command`
#! /usr/bin/env bash

# 輸出日期信息
echo `date`

Output:

$ sh test.sh
2020年07月 5日 8:48:25

6.使用echo命令將執行結果重定向

在某些情況下,我們可能需要將echo輸出的字符保存到文件中,這時就需要用到重定向。
下面是重定向字符:

  • > 當目標文件不存在時,創建文件,並將標準輸出保存到文件,文件存在時,則覆蓋原文件內容。
  • >> 當目標文件不存在時,創建文件,並將標準輸出保存到文件;文件存在時,則追加內容到文件末尾。
  • 1> 將正確輸出重定向到目標文件,這裏爲覆蓋操作。
  • 1>> 將正確輸出重定向到目標文件,這裏爲追加操作。
  • 2> 將錯誤輸出重定向到目標文件,這裏爲覆蓋操作。
  • 2>> 將錯誤輸出重定向到目標文件,這裏爲追加操作。
  • &> 意思是把標準輸出和標準錯誤輸出都重定向到目標文件中。
#! /usr/bin/env bash

# 輸出日期信息
echo `date` > date.txt

我們查看date.txt文件:

$ cat date.txt
2020年07月 5日 8:58:30

二、文本的格式化輸出

1.使用UNIX製表符

製表符的功能可以實現在不使用表格的情況下,在垂直方向上按列對齊文本,在Shell中水平製表符\t比較常見,下面我們使用製表符輸出乘法口訣表:

#! /usr/bin/env bash
result=0
for ((i=1;i<10;i++))
do
    for ((j=1;j<=$i;j++))
    do
        let result=i*j
        echo -n -e "$i*$j=$result\t"
    done
    echo ""
done

Output:

$ sh test.sh
1*1=1
2*1=2   2*2=4
3*1=3   3*2=6   3*3=9
4*1=4   4*2=8   4*3=12  4*4=16
5*1=5   5*2=10  5*3=15  5*4=20  5*5=25
6*1=6   6*2=12  6*3=18  6*4=24  6*5=30  6*6=36
7*1=7   7*2=14  7*3=21  7*4=28  7*5=35  7*6=42  7*7=49
8*1=8   8*2=16  8*3=24  8*4=32  8*5=40  8*6=48  8*7=56  8*8=64
9*1=9   9*2=18  9*3=27  9*4=36  9*5=45  9*6=54  9*7=63  9*8=72  9*9=81

2.使用fold命令格式化行

fold命令是將超過指定寬度的文本行進行摺疊處理,使得超過指定寬度的字符轉到下一行輸出。fold命令的語法如下:
fold [options] [file...]
在上面的語法中,options表示選項,fold命令常用的選項如下:

  • -b 按字節計算寬度。默認情況下fold命令按照列計算寬度。
  • -s在空格處折斷行。
  • -w指定寬度,默認值是80列。
    file參數用來指定要輸出的文件名,可以是多個文件,多個文件通過空格隔開。
    下面我們創建一個文件message.txt,內容如下:
$ cat message.txt
The WithCancel, WithDeadline, and WithTimeout functions take a Context (the parent) and return a derived Context (the child) and a CancelFunc.
Calling the CancelFunc cancels the child and its children, removes the parent's reference to the child, and stops any associated timers. Failing to
call the CancelFunc leaks the child and its children until the parent is canceled or the timer fires. The go vet tool checks that CancelFuncs are
used on all control-flow paths.

接下來我們使用fold命令指定輸出的列爲90:

$ fold -w 90 message.txt
The WithCancel, WithDeadline, and WithTimeout functions take a Context (the parent) and re
turn a derived Context (the child) and a CancelFunc.
Calling the CancelFunc cancels the child and its children, removes the parent's reference
to the child, and stops any associated timers. Failing to
call the CancelFunc leaks the child and its children until the parent is canceled or the t
imer fires. The go vet tool checks that CancelFuncs are
used on all control-flow paths.

我們可以看到這裏的列認爲每個字符爲一列,但是有個問題,我們可以看到,有的單詞被分成了兩個單詞,這個問題我們可以通過使用-s選項解決。

$ fold -s -w 90 message.txt
The WithCancel, WithDeadline, and WithTimeout functions take a Context (the parent) and
return a derived Context (the child) and a CancelFunc.
Calling the CancelFunc cancels the child and its children, removes the parent's reference
to the child, and stops any associated timers. Failing to
call the CancelFunc leaks the child and its children until the parent is canceled or the
timer fires. The go vet tool checks that CancelFuncs are
used on all control-flow paths.

我們可以看到所有的行尾單詞都是完整的。

3.使用fmt命令格式化段落

與fold命令相比,fmt命令提供了更多的功能,其基本語法如下:
fmt [-width] [option]... [file]...
其中-width選項用來指定文本行的列數,默認是75列,即每行顯示75個字符。options表示各種命令選項,常用的選項如下列:

  • -c 保留每個段落的前兩行的縮進,該段落剩餘的行的左邊距與第二行相同。
  • -t 與-c基本相同,但是在使用-t選項時,每個段落的第一行和第二行的縮進必須是不相同的,否則第一行將被看作一個單獨的段落。
  • -s 只折斷超出指定寬度的行,不合並超出指定寬度的行。
  • -u統一空格的個數,單詞之間保留一個空格,句子之間保留兩個空格。
  • -w 指定每個行的最大寬度,默認值爲75列。
    file參數爲要格式化的文件名,多個文件以空格隔開。
    下面舉個例子:
    我們將message的內容改成:
$ cat message.txt
    The WithCancel, WithDeadline, and WithTimeout functions take a Context (the parent) and
return a derived Context (the child) and a CancelFunc.Calling the CancelFunc cancels the child
and its children, removes the parent's reference to the child, and stops any associated timers.
    The WithCancel, WithDeadline

我們使用-w指定文本的寬度爲80列,-c讓每個文本段落前面兩行的縮進格式保留下來,-s參數避免行的合併。

$ fmt -c -s -w 70 message.txt
    The WithCancel, WithDeadline, and WithTimeout functions take
    a Context (the parent) and
return a derived Context (the child) and a CancelFunc.Calling the
CancelFunc cancels the child
and its children, removes the parent's reference to the child,
and stops any associated timers.
    The WithCancel, WithDeadline

注意:fmt命令着重於段落格式化,另外fmt的-w選項和fold命令的-w選項功能並不相同,前者會考慮單詞的完整性,後者則不會。

4.使用rev命令反轉字符順序

rev命令的功能是用來反轉文件中的文本行的字符順序,基本語法如下:
rev [file...]
其中file表示要處理的文件名列表,多個文件以空格隔開:
我們創建一個文件message.txt,內容如下:

$ cat message.txt
10 9 8 7 6 5 4 3 2 1
!dlroW olleH

反轉字符串:

$ rev message.txt
1 2 3 4 5 6 7 8 9 10
Hello World!

5.使用pr命令格式化文本頁

pr命令是一個非常有用的工具,其主要功能是將文本文件的內容轉換成適合打印的格式。基本語法如下:
pr [options] [file]...
同樣options表示命令選項,file表示文件,多個文件以空格隔開。
常用的選項如下:

  • -column 指定輸出的欄數,默認值爲1
  • -a 修改column的顯示效果,水平創建欄,與column配合使用。
  • -d 產生兩個空格的輸出。
  • -F或者-f 使用換頁符代替換行符實現分頁。
  • -h 指定頁眉,如果沒有指定,則使用文件名稱作爲頁眉。
  • -l 指定每頁的行數,默認爲66行。
  • -o 指定每行的縮進的字符數量。
  • -w 指定頁面寬度,默認爲72個字符。

注意:使用column指定的寬度不能超過屏幕寬度,另外默認情況下,pr命令的分欄是垂直劃分的。

我們創建一個文件message.txt,文件內容如下:

$ cat message.txt
Context
parent
and
return
derived
Context
CancelFunc
Calling
CancelFunc
cancels
the
child
its
children
removes
the
parent's
reference
child
and
stops
any
associated
timers

接下來我們使用pr命令格式化輸出:

[root@random_wz ~]# pr -h "list word" -f  -4 -a message.txt


2020-07-05 10:50                    list word                     Page 1


Context           parent            and               return
derived           Context           CancelFunc        Calling
CancelFunc        cancels           the               child
its               children          removes           the
parent's          reference         child             and
stops             any               associated        timers
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章