理解shell脚本 - IFS,'' ,##

时间:2014-08-08 06:19:56

标签: linux shell

我是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")

提前感谢 :)

3 个答案:

答案 0 :(得分:2)

第一行用于读取grep -ZFlR "$str" "$dir"传递的原始输入。

while IFS= read -rd '' file;

正如您在-Z中指定grep一样,它会输出一个零字节而不是换行符分隔的新行分隔文件名。所以在read命令中也指定了一个引用分隔符的-d选项。 至于IFS=,用于清空IFS(内部字段分隔符)以保留前导和尾随空格。更多阅读here

下一行:

base=${file##*/}

删除任何字符的最长匹配,以$file前面的斜线结尾。所以类似:

/abc/def/jhg

-------->

strips off /abc/def/

同样第三行:

dir=${file%/*}

从$ file的末尾删除最短匹配。

/abc/def/jhg

        <----

strips off /jhg. 

更多阅读here

由于您没有询问最后一行,我假设您已经熟悉它被重定向到while循环。

答案 1 :(得分:2)

while IFS= read -rd '' file;   #What '' is doing?
do

while while循环将读取命令(exec grep -ZFlR "$str" "$dir")返回的每一行。您看到它已被用于'提供'数据到最后的循环:done < <(exec grep -ZFlR "$str" "$dir")while循环开始,您会看到IFS=。 bash中的unsets Internal Field SeparatorIFS)确定将给定字符串分隔为单独字段的内容。 (默认情况下,IFS = $'空格标签换行符',您看起来像IFS=$' \t\n')

while循环继续read -rd '' file;正如所讨论的那样,输入来自最后的exec grep..表达式,read -rd '' file正在读取输入直到第一个{{ 1 {}由''指定为与此-d 一起使用的分隔符。 read然后将匹配的输入存储在变量read中。 因此file仅用作'' read选项-d指定的read分隔符。(这解释了为什么{{1}一开始是未设置,他们希望在这种情况下使用特定的IFS分隔符。

''

所有这一切都是使用 base=${file##*/} #Please explain 删除parameter expansion中从开始直到(并包括)最后一个string中的eveything 1}}角色。 (这就是/的含义)。 它正在从文件名中提取路径信息,只留下## 中的文件名。

base

这是类似的参数扩展,但在这里,我们从dir=${file%/*} #Please explain )开始,删除所有字符,包括第一个%字符在/ 中仅保留file 中的path个信息。 (有道理)

dir

如上所述,只需输入循环。

答案 2 :(得分:0)

$ file从read获取其值,而<( ... )又从输入读取,该输入在循环结束时被重定向到。 ##被称为&#34;进程替换&#34;,它基本上表现为一个文件,其内容是所附命令的输出。 %man bash是&#34;参数展开&#34;的实例,它们会删除变量值的部分内容。您可以在{{1}}。

中搜索所有字词和结构