Nat*_*tal 6 zsh variable-substitution
我遇到了一个 Zsh 脚本,想知道它的含义。在下面的脚本中有${$(@f)$(egrep "$2","$file")}表达式。从我搜索到的,@是使用代表所有位置参数,但是f上面脚本中的任何地方都没有提到后缀字母,我找不到任何在线资料说明其特殊含义。
#!/usr/bin/env zsh
tmp_file="/tmp/_unsorted_find_n_grep"
echo "--- find <$2> in <$1>" > $tmp_file
find . -follow -iname "$1" | while read file
do
timestamp=$(ls -l --time-style=+"%Y-%m-%d %H:%M:%S" "$file" | gawk '{print $6, $7}')
linestack=${(@f)$(egrep "$2" "$file")}
for line in $linestack
do
echo "$timestamp $file: $line" >> $tmp_file
done
done
cat $tmp_file | sort
rm $tmp_file
Run Code Online (Sandbox Code Playgroud)
括号内的字符是参数扩展标志。它们可以用于变量替换或命令替换,例如
${(@f)SOME_VARIABLE}
${(@f)${(xyz)SOME_VARIABLE}}
${(@f)$(some-command)}
Run Code Online (Sandbox Code Playgroud)
该标志f在换行符处分割扩展的结果。该标志@确保将结果数组扩展为多个字;奇怪的是,它只在双引号内有效,它充当"$@".
通常,这些标志的使用方式如下:
lines=("${(@f)$(egrep "$2" "$file")}")
Run Code Online (Sandbox Code Playgroud)
这种方式lines成为一个数组,其中每个元素都是 的一行输出egrep。
这里,扩展不是在允许多个单词的上下文中,因此该@标志不起作用。该f标志的效果有些不直观:它强制使用数组上下文,因此输出中以 IFS 分隔的单词egrep存储在临时数组中,然后与 的第一个字符连接IFS。
Run Code Online (Sandbox Code Playgroud)linestack=${(@f)$(egrep "$2" "$file")}
对比:
$ zsh -c 'a=${(f)$(echo hello world; echo wibble)}; print -lr $#a $a'
18
hello world wibble
$ zsh -c 'IFS=:$IFS; a=${(f)$(echo hello world; echo wibble)}; print -lr $#a $a'
18
hello:world:wibble
$ zsh -c 'IFS=:; a=${(f)$(echo hello world; echo wibble)}; print -lr $#a $a'
18
hello world
wibble
$ zsh -c 'a=(${(f)$(echo hello world; echo wibble)}); print -lr $#a $a'
1
hello world wibble
$ zsh -c 'a=("${(@f)$(echo hello world; echo wibble)}"); print -lr $#a $a'
2
hello world
wibble
Run Code Online (Sandbox Code Playgroud)
@ In double quotes, array elements are put into separate words. E.g., \xe2\x80\x98"${(@)foo}"\xe2\x80\x99\n is equivalent to \xe2\x80\x98"${foo[@]}"\xe2\x80\x99 and \xe2\x80\x98"${(@)foo[1,2]}"\xe2\x80\x99 is the same as \xe2\x80\x98"$foo[1]"\n "$foo[2]"\xe2\x80\x99. This is distinct from field splitting by the f, s or z flags, which still\n applies within each array element.\nRun Code Online (Sandbox Code Playgroud)\n