[英]understanding shell script— IFS, '' , ##
我對Shell腳本非常陌生。 任何人都可以用一種非常簡單的語言在下面的行中向我解釋一下,或者給我一些鏈接,使我可以按照下面的代碼編寫的方式確切地找到要搜索的含義:
文件如何獲取價值? 完成后是否從grep命令獲取?
dir=$1 str=$2
while IFS= read -rd '' file; #What '' is doing?
do
base=${file##*/} #Please explain
dir=${file%/*} #Please explain
done < <(exec grep -ZFlR "$str" "$dir")
在此先感謝一噸:)
第一行用於讀取grep -ZFlR "$str" "$dir"
傳遞的原始輸入。
while IFS= read -rd '' file;
正如您在grep
指定-Z
,它將輸出一個零字節,而不是grep
通常會用換行符分隔的文件名。 因此,在read命令中還使用了-d
選項來引用分隔符。 至於IFS=
,這樣做是為了清空IFS(內部字段分隔符),以保留前導和尾隨空白。 在這里閱讀更多
下一行:
base=${file##*/}
從$file
刪除以斜杠結尾的任何字符的最長匹配。
/abc/def/jhg
-------->
strips off /abc/def/
第三行類似:
dir=${file%/*}
從$ file末尾刪除最短的匹配項。
/abc/def/jhg
<----
strips off /jhg.
在這里閱讀更多。
正如您沒有詢問最后一行一樣,我假設您已經熟悉將其重定向到while循環。
while IFS= read -rd '' file; #What '' is doing?
do
Thie while循環將讀取命令返回的每一行(exec grep -ZFlR "$str" "$dir")
。 您會看到它最后被用於將數據“饋送”到循環中: done < <(exec grep -ZFlR "$str" "$dir")
從while
循環開始,您會看到IFS=
。 這會在bash中unsets
設置Internal Field Separator
( IFS
),該Internal Field Separator
確定將給定的單詞字符串分隔為單獨的字段的原因。 (默認的IFS = $'空格標簽換行符',您會看到它類似於IFS=$' \\t\\n')
while循環繼續read -rd '' file;
如所討論的,輸入來自末尾的exec grep..
表達式,而read -rd '' file
正在讀取該輸入, 直到第一個''
由-d
指定)為該read
使用的分隔符 。 read
然后將匹配的輸入存儲在變量file
。 所以''
只是作為分隔符用於read
由指定-d
選項來read
。 (這說明了為什么一開始未設置 IFS
,他們想在這種情況下使用特定的''
分隔符。
base=${file##*/} #Please explain
這一切都是使用parameter expansion
來刪除string
中從左到最后( 包括 )最后一個/
字符的傳送。 (這就是##
意思)。 它從文件名中粘貼路徑信息,僅將文件名保留在base
。
dir=${file%/*} #Please explain
在這里,這是類似的參數擴展,但在這里,我們從右邊 (起始%
),並刪除所有的字符,直到達到,並且包括,第一/
字符file
只留下path
信息dir
。 (說得通)
done < <(exec grep -ZFlR "$str" "$dir")
就像我們上面討論的那樣,只提供循環。
$ file從read
獲取其值,后者又從輸入中讀取內容,然后將其重定向到循環的末尾。 <( ... )
稱為“進程替換”,它基本上就像一個文件,其內容是附帶命令的輸出。 ##
和%
是“參數擴展”的實例,它們刪除變量值的一部分。 您可以在man bash
搜索所有術語和構造。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.