我是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")
提前感谢 :)
答案 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 Separator
(IFS
)确定将给定字符串分隔为单独字段的内容。 (默认情况下,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}}。