初寫(xiě)shell 時(shí)遇到的一些問(wèn)題

一. 逐行處理文本

1.通過(guò)read命令完成.

read命令接收標(biāo)準(zhǔn)輸入,或其他文件描述符的輸入,得到輸入后,read命令將數(shù)據(jù)放入一個(gè)標(biāo)準(zhǔn)變量中。

利用read讀取文件時(shí),每次調(diào)用read命令都會(huì)讀取文件中的"一行"文本。

當(dāng)文件沒(méi)有可讀的行時(shí),read命令將以非零狀態(tài)退出。

cat data.dat | while read line;do
  echo "File:${line}" 
done
while read line;do 
  echo "File:${line}" 
done < data.dat

2.使用awk命令完成

awk是一種優(yōu)良的文本處理工具,提供了極其強(qiáng)大的功能.

利用awk讀取文件中的每行數(shù)據(jù),并且可以對(duì)每行數(shù)據(jù)做一些處理,還可以單獨(dú)處理每行數(shù)據(jù)里的每列數(shù)據(jù).

cat data.dat | awk '{print $0}'
cat data.dat | awk 'for(i=2;i<NF;i++) {printf $i} printf "\n"}'

第1行代碼輸出data.dat里的每行數(shù)據(jù),第2代碼輸出每行中從第2列之后的數(shù)據(jù).

如果是單純的數(shù)據(jù)或文本文件的按行讀取和顯示的話,使用awk命令比較方便.

3.使用for var in file 命令完成

for var in file 表示變量var在file中循環(huán)取值.取值的分隔符由$IFS確定.

for line in $(cat data.dat);do
  echo "File:${line}"
done
# 或
for line in `cat data.dat`;do
  echo "File:${line}"
done

如果輸入文本每行中沒(méi)有空格,則 line 在輸入文本中按換行符分隔符循環(huán)取值。如果輸入文本中包括空格或制表符,則不是換行讀取,line 在輸入文本中按空格分隔符或制表符或換行符特環(huán)取值,可以通過(guò)把 IFS 設(shè)置為換行符來(lái)達(dá)到逐行讀取的功能。

IFS的默認(rèn)值為:空白(包括:空格,制表符,換行符).

注意:
這段代碼

path_all=""
cat test.txt | while read line
do
    path_all="${path_all} ${line}"
done
echo $path_all

這段代碼的本意是將test 文件中的文本按行讀出并拼接成一行,但最后的輸出卻是空串,出現(xiàn)這種問(wèn)題的原因和while 有關(guān),
while循環(huán)讀取文件中內(nèi)容有兩種寫(xiě)法,一種是管道符,一種是重定向,寫(xiě)法如下

管道符:

cat $file_name | while read line
do
  #deal with line
done

重定向:

while read line
do
  #deal with line
done < $file_name

這兩種做法的區(qū)別在于,重定向是內(nèi)建命令,而管道符是非內(nèi)建命令,之所以我寫(xiě)的腳本出現(xiàn)了輸出是空的問(wèn)題,原因就在這里,linux執(zhí)行shell時(shí),會(huì)創(chuàng)建“子shell”運(yùn)行shell中的命令,當(dāng)運(yùn)行到非內(nèi)建指令時(shí),會(huì)創(chuàng)建“孫shell”運(yùn)行非內(nèi)建指令,變量的作用于在每個(gè)shell中有效,所以,非內(nèi)建指令中定義的這些變量就只能在孫shell運(yùn)行,而在子shell中不生效,所以,即便在while中給path_all賦值了,子shell中也不會(huì)獲取到這個(gè)值。

解決這個(gè)問(wèn)題的辦法有兩種,如果不是必須使用管道符的方式寫(xiě)while循環(huán),可以用重定向的寫(xiě)法,這種寫(xiě)法循環(huán)內(nèi)的變量在子shell中是生效的,比較簡(jiǎn)便;如果非要使用管道符的方式,可以創(chuàng)建臨時(shí)文件,用于存放孫shell中的輸出。

二. 字符串截取

假設(shè)有變量 var=http://www.aaa.com/123.htm.

1. # 號(hào)截取,刪除左邊字符,保留右邊字符。 (非貪婪匹配)

echo ${var#*/}

其中 var 是變量名,# 號(hào)是運(yùn)算符,*/ 表示從左邊開(kāi)始刪除第一個(gè) / 號(hào)及左邊的所有字符
即刪除 http://
結(jié)果是 :www.aaa.com/123.htm

2. ## 號(hào)截取,刪除左邊字符,保留右邊字符。(貪婪匹配)

echo ${var##*/}

##*/ 表示從左邊開(kāi)始刪除最后(最右邊)一個(gè) / 號(hào)及左邊的所有字符
即刪除 http://www.aaa.com/

結(jié)果是 123.htm

3. %號(hào)截取,刪除右邊字符,保留左邊字符 (非貪婪匹配)

echo ${var%/*}

%/* 表示從右邊開(kāi)始,刪除第一個(gè) / 號(hào)及右邊的字符

結(jié)果是:http://www.aaa.com

4. %% 號(hào)截取,刪除右邊字符,保留左邊字符 (貪婪匹配)

echo ${var%%/*}

%%/* 表示從右邊開(kāi)始,刪除最后(最左邊)一個(gè) / 號(hào)及右邊的字符
結(jié)果是:http:

5. 從左邊第幾個(gè)字符開(kāi)始,及字符的個(gè)數(shù)

echo ${var:0:5}

其中的 0 表示左邊第一個(gè)字符開(kāi)始,5 表示字符的總個(gè)數(shù)。
結(jié)果是:http:

6. 從左邊第幾個(gè)字符開(kāi)始,一直到結(jié)束。

echo ${var:7}

其中的 7 表示左邊第8個(gè)字符開(kāi)始,一直到結(jié)束。
結(jié)果是 :www.aaa.com/123.htm

7. 從右邊第幾個(gè)字符開(kāi)始,及字符的個(gè)數(shù)

echo ${var:0-7:3}

其中的 0-7 表示右邊算起第七個(gè)字符開(kāi)始,3 表示字符的個(gè)數(shù)。
結(jié)果是:123

8. 從右邊第幾個(gè)字符開(kāi)始,一直到結(jié)束。

echo ${var:0-7}

表示從右邊第七個(gè)字符開(kāi)始,一直到結(jié)束。
結(jié)果是:123.htm

注:(左邊的第一個(gè)字符是用 0 表示,右邊的第一個(gè)字符用 0-1 表示)

9. 字符串分割

大多數(shù)語(yǔ)言中都有類(lèi)似string.split('sp') 的方法將字符串按照某個(gè)字符或子串切分成一個(gè)數(shù)組,shell 中可以如下

str="hello,world,i,like,you,babalala"
arr=(${str//,/ })

將str按照','切分成一個(gè)數(shù)組,并遍歷之。當(dāng)然,這里分隔符可以是一個(gè)子串。

三. 數(shù)組的操作

1. 定義數(shù)組

declare -a array              # 顯示聲明了數(shù)組array
delcare -a array[10]          # 數(shù)組大小沒(méi)有上限,所以定義時(shí)指定的大小會(huì)被忽略
array[key]=value              # array[0]=one,array[1]=two
array=(value1 value2...)   # value的形式都是[subscript]=string,下標(biāo)和等號(hào)可以省略,示例如下。
array=(value1 value2 value3) # array[0]=value1,array[1]=value2,array[2]=value3
array=([0]=value1 [2]=value3 [3]=value)

2. 訪問(wèn)數(shù)組

數(shù)組的任何元素都可以用 ${array[subscript]} 來(lái)引用,花括號(hào)是必須的,以避免和路徑擴(kuò)展沖突。 如果 subscript 是@或是*,它擴(kuò)展為array的所有成員。這兩種下標(biāo)只有在雙引號(hào)中才不同。在雙引號(hào)中,${name[*]} 擴(kuò)展為一個(gè)詞,由所有數(shù)組成員的值組成,用特殊變量IFS的第一個(gè)字符分隔數(shù)組成員;${array[@]} 將array 的每個(gè)成員擴(kuò)展為一個(gè)詞。 如果數(shù)組沒(méi)有成員,${name[@]} 擴(kuò)展為空串。

3. 其他更多

請(qǐng)見(jiàn)https://www.thegeekstuff.com/2010/06/bash-array-tutorial/

四. 變量

1. 作用域
http://c.biancheng.net/view/773.html

2. 比較
https://blog.csdn.net/u010622613/article/details/80706119

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,718評(píng)論 0 5
  • 一、Python簡(jiǎn)介和環(huán)境搭建以及pip的安裝 4課時(shí)實(shí)驗(yàn)課主要內(nèi)容 【Python簡(jiǎn)介】: Python 是一個(gè)...
    _小老虎_閱讀 6,339評(píng)論 0 10
  • 一,shell題記 不懂shell的程序員不是好程序員,學(xué)習(xí)shell是為了自動(dòng)化,使用自動(dòng)化可以非常有效的提高工...
    架構(gòu)師小秘圈閱讀 8,793評(píng)論 3 70
  • 基礎(chǔ)命令 主要的命令和快捷鍵 Linux系統(tǒng)命令由三部分組成:cmd + [options]+[operation...
    485b1aca799e閱讀 1,222評(píng)論 0 0
  • 指針是C語(yǔ)言中廣泛使用的一種數(shù)據(jù)類(lèi)型。 運(yùn)用指針編程是C語(yǔ)言最主要的風(fēng)格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,615評(píng)論 3 44

友情鏈接更多精彩內(nèi)容