一行bash編程技巧

1. 清空文件內(nèi)容

$ > file

這一行命令用到了輸出重定向操作符>。輸出重定向發(fā)生時(shí)驮肉,文件會(huì)被打開準(zhǔn)備寫入涣雕。如果此時(shí)文件不存在則先創(chuàng)建,存在則將其大小截取為0装处。這里我們并沒有重定向?qū)懭魏蝺?nèi)容到文件中误债,所以文件依然保持為空浸船。

如果你想替換文件的內(nèi)容,或者創(chuàng)建一個(gè)包含指定內(nèi)容的文件寝蹈,可以運(yùn)行下面的命令:

$ echo "some string" > file

2. 追加內(nèi)容到文件

$ echo "foo bar baz" >> file

這一行命令用到了另外一個(gè)輸出重定向操作符>>李命,該操作符將內(nèi)容追加到文件。同樣地箫老,如果文件不存在則先創(chuàng)建它封字。追加的內(nèi)容之后,緊跟著換行符耍鬓。如果你不想要追加換行符阔籽,在執(zhí)行echo命令時(shí)可以指定-n選項(xiàng):

$ echo -n "foo bar baz" >> file

3. 讀取文件的首行并賦值給變量

$ read -r line < file

這一行命令用到了 Bash 的內(nèi)置命令read,和輸入重定向操作符<牲蜀。read命令從標(biāo)準(zhǔn)輸入中讀取一行笆制,并將內(nèi)容保存到變量line中。在這里各薇,-r選項(xiàng)保證讀入的內(nèi)容是原始的內(nèi)容项贺,意味著反斜杠轉(zhuǎn)義的行為不會(huì)發(fā)生。輸入重定向操作符< file打開并讀取文件file峭判,然后將它作為read命令的標(biāo)準(zhǔn)輸入开缎。

記住,read命令會(huì)刪除包含在IFS變量中出現(xiàn)的所有字符林螃,IFS 的全稱是 Internal Field Separator奕删,Bash 根據(jù) IFS 中定義的字符來分隔單詞。在這里疗认,read命令讀入的行被分隔成多個(gè)單詞完残。默認(rèn)情況下,IFS包含空格横漏,制表符和回車谨设,這意味著開頭和結(jié)尾的空格和制表符都會(huì)被刪除。如果你想保留這些符號(hào)缎浇,可以通過設(shè)置IFS為空來完成:

$ IFS= read -r line < file

IFS 的變化僅會(huì)影響當(dāng)前的命令扎拣,這行命令可以保證讀入原始的首行內(nèi)容到變量line中,同時(shí)行首與行尾的空白字符被保留素跺。

另外一種讀取文件首行內(nèi)容二蓝,并賦值給變量的方法是:

$ line=$(head -1 file)

這里用到了命令替換操作符$(...),它運(yùn)行括號(hào)里的命令并且將輸出返回指厌。 這個(gè)例子中刊愚,命令是head -1 file,輸出的內(nèi)容是文件的首行踩验。輸入然后通過等號(hào)賦值給變量line鸥诽。$(...)的等價(jià)寫法是`...`商玫,所以也可以換成下面這樣:

$ line=`head -1 file`

不過,在 Bash 中$(...)用法更加推薦衙传,因?yàn)樗雌饋砀诱麧嵕鎏⑶胰菀浊短资褂谩?/p>

4. 依次讀入文件每一行

$ while read -r line; do

? ? # do something with $line

done < file

這是一種正確的讀取文件內(nèi)容的做法,read命令放在while循環(huán)中蓖捶。當(dāng)read命令遇到文件結(jié)尾時(shí)(EOF)地回,它會(huì)返回一個(gè)正值,導(dǎo)致循環(huán)判斷失敗終止俊鱼。

記住刻像,read命令會(huì)刪除首尾多余的空白字符,所以如果你想保留并闲,請(qǐng)?jiān)O(shè)置 IFS 為空值:

$ while IFS= read -r line; do

? ? # do something with $line

done < file

如果你不想將< file放在最后细睡,可以通過管道將文件的內(nèi)容輸入到 while 循環(huán)中:

$ cat file | while IFS= read -r line; do

? ? # do something with $line

done

5. 隨機(jī)讀取一行并賦值給變量

$ read -r random_line < <(shuf file)

Bash 中并沒有提供一種直接的方法來隨機(jī)讀取文件的某一行內(nèi)容,所以這里需要利用外部程序帝火。在最新的一些 Linux 系統(tǒng)上溜徙,GNU Coreutils 包中提供的shuf命令可以滿足我們的需求。

這一行命令中用到了進(jìn)程替換(process substitution)操作符<(...)犀填。進(jìn)程替換操作會(huì)創(chuàng)建一個(gè)匿名的管道文件蠢壹,并將進(jìn)程命令的標(biāo)準(zhǔn)輸出連接到管道的寫一端。然后 Bash 開始執(zhí)行進(jìn)程替換中的命令九巡,然后將整個(gè)進(jìn)程替換的表達(dá)式替換成匿名管道的文件名图贸。

當(dāng) Bash 看到<(shuf file)時(shí),它首先打開一個(gè)特殊的文件/dev/fd/n冕广,這里的n是一個(gè)空閑的文件描述符疏日,然后執(zhí)行shuf file命令,將標(biāo)準(zhǔn)輸出連接到/dev/fd/n撒汉,并且替換<(shuf file)為/dev/fd/n沟优,因此實(shí)際的命令會(huì)變成:

$ read -r random_line < /dev/fd/n

結(jié)果會(huì)讀取洗牌后的文件的第一行內(nèi)容。

另外一種做法是睬辐,使用 GNU sort 命令挠阁,它提供的-R選項(xiàng)可以隨機(jī)排序文件:

$ read -r random_line < <(sort -R file)

或者,同前面一樣溉委,將結(jié)果賦值給變量:

$ random_line=$(sort -R file | head -1)

這里鹃唯,我們首先通過sort -R隨機(jī)排序文件爱榕,然后通過head -1讀取文件的第一行瓣喊。

6. 讀取文件首行前三個(gè)字段并賦值給變量

$ while read -r field1 field2 field3 throwaway; do

? ? # do something with $field1, $field2, and $field3

done < file

如果在read命令中指定多個(gè)變量名,它會(huì)將讀入的內(nèi)容分隔成多個(gè)字段黔酥,然后依次賦值給對(duì)應(yīng)的變量藻三,第一個(gè)字段賦值給第一個(gè)變量洪橘,第二個(gè)字段賦值給第二個(gè)變量,等等棵帽,最后將剩余的所有字段賦值給最后一個(gè)變量熄求。這也是為什么,在上面的例子中逗概,我們加了一個(gè)throwaway變量弟晚,否則的話,當(dāng)文件的一行大于三個(gè)字段時(shí)逾苫,第三個(gè)變量的內(nèi)容會(huì)包含所有剩余的字段卿城。

有時(shí)候,為了書寫方便铅搓,可以簡(jiǎn)單地用_來替換throwaway變量:

$ while read -r field1 field2 field3 _; do

? ? # do something with $field1, $field2, and $field3

done < file

又或者瑟押,如果你的文件確實(shí)只有三個(gè)字段,那可以忽略它:

$ while read -r field1 field2 field3; do

? ? # do something with $field1, $field2, and $field3

done < file

下面是一個(gè)例子星掰,假如你想知道一個(gè)文件到底包含多少行多望,多少個(gè)單詞以及多少個(gè)字節(jié)。當(dāng)你執(zhí)行wc命令時(shí)氢烘,你會(huì)得到3個(gè)數(shù)字加上文件名怀偷,文件名在最后:

$ cat file-with-5-lines

x 1

x 2

x 3

x 4

x 5

$ wc file-with-5-lines

5 10 20 file-with-5-lines

所以,這個(gè)文件包含5行威始,10個(gè)單詞枢纠,以及20個(gè)字符。我們接下來黎棠,可以通過read命令將這些信息保存到變量中:

$ read lines words chars _ < <(wc file-with-5-lines)

$ echo $lines

5

$ echo $words

10

$ echo $chars

20

類似地晋渺,你也可以使用here-strings將字符串分隔并保存到變量中。假設(shè)你有一個(gè)字符串變量$info脓斩,內(nèi)容為"20 packets in 10 seconds"木西,然后你想要將從中獲取20和10。在不久之前随静,我是這樣來完成的:

$ packets=$(echo $info | awk '{ print $1 }')

$ time=$(echo $info | awk '{ print $4 }')

然而八千,得益于read命令的強(qiáng)大和對(duì) Bash 的了解,我們可以這樣做:

$ read packets _ _ time _ <<< "$info"

這里燎猛,<<<就是 here-string 的語法恋捆,它允許你直接傳遞字符串給標(biāo)準(zhǔn)輸入。

7. 保存文件的大小到變量

$ size=$(wc -c < file)

這一行命令中用到了第3點(diǎn)中介紹的命令替換操作$(...)重绷,它運(yùn)行里面的命令并將結(jié)果獲取回來沸停。在這個(gè)例子中,命令是wc -c < file昭卓,它輸出文件的字節(jié)數(shù)愤钾。這個(gè)結(jié)果最終會(huì)賦值給變量size瘟滨。

8. 從文件路徑中獲取文件名

假設(shè),你有一個(gè)文件能颁,它的路徑為/path/to/file.ext杂瘸,然后你要從中獲取文件名,在這里是file.ext伙菊。你要怎么做败玉? 一個(gè)好的方法是通過參數(shù)展開(parameter expansion)功能:

$ filename=${path##*/}

這一行命令使用了參數(shù)展開的語法:${var##pattern},它從$var字符串開始處開始匹配pattern镜硕。如果能夠匹配成功绒怨,將最長(zhǎng)匹配的內(nèi)容刪除后再返回。

在這個(gè)例子中谦疾,匹配的模式是*/南蹂,它嘗試匹配/path/to/file.ext的開始部分,正如前面所說念恍,這里是貪婪匹配六剥,所以它能夠匹配到最后一個(gè)斜杠為止,即匹配的內(nèi)容是/path/to/峰伙。所以當(dāng)把匹配的內(nèi)容刪除后疗疟,返回的內(nèi)容就是文件名file.ext。

9. 從文件路徑中獲取目錄名

和上面一樣類似瞳氓,這次你要從路徑/path/to/file.txt中獲取目錄名/path/to策彤。你可以繼續(xù)通過參數(shù)展開功能來完成這個(gè)任務(wù):

$ dirname=${path%/*}

這次的用法是${var%pattern},它從$var的結(jié)尾處匹配/*匣摘。如果能夠成功匹配店诗,將最短匹配的內(nèi)容刪除再返回。

在這個(gè)例子中音榜,匹配的模式是/*庞瘸,它能夠匹配/file.ext部分,刪除這部分內(nèi)容后返回的就是目錄名稱赠叼。

10. 快速拷貝文件

假設(shè)你要將文件/path/to/fil拷貝到/path/to/file_copy擦囊,一般情況下,大多數(shù)人會(huì)這么來寫:

$ cp /path/to/file /path/to/file_copy

不過,你可以利用括號(hào)展開(brace expansion){...}功能:

$ cp /path/to/file {,_copy}

括號(hào)展開可以生成任意字符串的組合,在這個(gè)例子中躲庄,/path/to/file{,_copy}最終生成/path/to/file /path/to/file_copy。所以上面這行命令最終發(fā)型成:

$ cp /path/to/file /path/to/file_copy

類似地贯被,你可以執(zhí)行下面的命令快速的移動(dòng)文件:

$ mv /path/to/file{,_old}

這行命令展開后就變成了:

$ mv /path/to/file /path/to/file_old

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子刃榨,更是在濱河造成了極大的恐慌,老刑警劉巖双仍,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枢希,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡朱沃,警方通過查閱死者的電腦和手機(jī)苞轿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逗物,“玉大人搬卒,你說我怎么就攤上這事◆嶙浚” “怎么了契邀?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)失暴。 經(jīng)常有香客問我坯门,道長(zhǎng),這世上最難降的妖魔是什么逗扒? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任古戴,我火速辦了婚禮,結(jié)果婚禮上矩肩,老公的妹妹穿的比我還像新娘现恼。我一直安慰自己,他們只是感情好黍檩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布叉袍。 她就那樣靜靜地躺著,像睡著了一般刽酱。 火紅的嫁衣襯著肌膚如雪畦韭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天肛跌,我揣著相機(jī)與錄音艺配,去河邊找鬼。 笑死衍慎,一個(gè)胖子當(dāng)著我的面吹牛转唉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播稳捆,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赠法,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起砖织,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤款侵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后侧纯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體新锈,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年眶熬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妹笆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡娜氏,死狀恐怖拳缠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贸弥,我是刑警寧澤窟坐,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站绵疲,受9級(jí)特大地震影響狸涌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜最岗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一帕胆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧般渡,春花似錦懒豹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝴乔,卻和暖如春记餐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背薇正。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工片酝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挖腰。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓雕沿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親猴仑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子审轮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,380評(píng)論 0 5
  • 1.創(chuàng)建文件夾 !/bin/sh mkdir -m 777 "%%1" 2.創(chuàng)建文件 !/bin/sh touch...
    BigJeffWang閱讀 10,051評(píng)論 3 53
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多,請(qǐng)查閱幫助信息) 1、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,094評(píng)論 1 19
  • 文/黃梅枝 王娟看到爸爸的樣子很傷心疾渣,王慧氣得在病房里搓手打轉(zhuǎn)轉(zhuǎn)篡诽,王慧略帶責(zé)怪王娟的口氣說:“娟子你也忒沒有脾氣了...
    黃梅枝閱讀 963評(píng)論 23 24
  • 年初五清晨,我們被圍觀榴捡。 醫(yī)院門前杈女,我和媽媽下車。 你們從哪里來薄疚? 指揮停車的老頭兒,頭發(fā)斑白赊琳,好似看到原始人一樣...
    蘭露兒閱讀 549評(píng)論 13 15