我注意到设置换行符IFS应该以 $ 作为前缀
IFS=$'\n'
Run Code Online (Sandbox Code Playgroud)
但如果设置一个冒号,就
IFS=:
Run Code Online (Sandbox Code Playgroud)
是\n变量吗?
Sté*_*las 21
那$'...'inbash不是参数扩展,它是一种特殊的引用,由 引入ksh93,将那些\n, \x0a,\12代码扩展为换行符。zsh还补充道\u000a。ksh93并且bash也有\cj同时zsh拥有\C-J。ksh93还支持像\x{a}.
这$是一个暗示它是某种形式或扩展。但在任何情况下,它与使用$(如$((1 + 1)),$param或$(cmd))的其他形式的扩展不同,因为它不在双引号或此处的文档中执行(尽管所有 shell 中的echo "$'x'"输出$'x'均未根据 POSIX 指定)并且其扩展不受拆分+glob,它绝对比扩展运算符更接近引用运算符。
IFS=\n将 IFS 设置为n(\被视为引用运算符) 和IFS="\n"或IFS='\n'将 IFS 设置为两个字符反斜杠和n。
您还可以使用:
IFS='
'
Run Code Online (Sandbox Code Playgroud)
或者
IFS="
"
Run Code Online (Sandbox Code Playgroud)
或者
IFS=$'
'
Run Code Online (Sandbox Code Playgroud)
传递一个文字换行符,尽管这不太清晰(除了使用诸如set listinvi是否$IFS包含该代码中的其他间距字符之类的东西之外,人们无法看到)。
IFS=:, IFS=':', IFS=":",IFS=$':'都将 IFS 设置为,:因此您使用哪个并不重要。
$'...'至少支持(有变化):ksh93, zsh, bash, mksh, busybox sh, FreeBSD sh。ksh93并且bash还有一种$"..."用于文本本地化的引号形式,尽管它很少使用,因为部署和使用便携和可靠很麻烦。
在es与fish壳还可以使用\n引号以外拓展到新行。
一些工具,如printf、echo或 的一些实现也awk可以\n自行扩展。例如,可以这样做:
printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only
Run Code Online (Sandbox Code Playgroud)
到换行符的输出,但请注意:
IFS=$(printf '\n')
将不起作用,因为命令替换 ( $(...)) 会删除所有尾随换行符。但是,您可以使用:
eval "$(printf 'IFS="\n"')"
Run Code Online (Sandbox Code Playgroud)
之所以有效,是因为输出printf以"字符结尾,而不是换行符。
现在,为了完整性,在rcshell 和派生类(如es或akanga)中,$'\n'确实是该\n变量的扩展(名称是两个字符\和的序列的变量n)。这些 shell 对变量名称可以包含的字符没有限制,并且只有一种类型的引号:'...'.
$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo
Run Code Online (Sandbox Code Playgroud)
rc变量也全部导出到环境中,但至少在 的 Unix 变体中rc,对于像 一样的变量名称\n,环境变量版本经历了一种编码形式:
; env | grep foo | sed -n l
__5cn=foo\001bar$
Run Code Online (Sandbox Code Playgroud)
(0x5c作为 ASCII 的字节值\;另请参阅该数组变量是如何使用 0x1 字节作为分隔符进行编码的)。
字符串 like$'\n'已经被引入ksh93并且目前不是 POSIX 标准的一部分。
它们允许使用大多数类似 C 的转义,例如$'\u2345',也支持的转义echo。
请注意,如果您不喜欢(在 ksh93 或 bash 的情况下)使用该转义方法,您仍然可以使用:
IFS='
'
Run Code Online (Sandbox Code Playgroud)
这是等效的,但更难阅读。
BTW:这个扩展已经通过了 POSIX 标准委员会,但它计划在SUSv8中出现,预计不会在 2020 年之前出现,因为我们首先需要解决我们落后于当前错误列表的问题。
| 归档时间: |
|
| 查看次数: |
3161 次 |
| 最近记录: |