bash shell脚本的开头是以下行:

IFS=$'\n'


这组符号的含义是什么?

评论

另请参见unix.stackexchange.com/questions/26784/understanding-ifs及其引用的问题。

vim语法对我来说是一个错误。解决?

IFS = $'\ n'是bashism(+其他shell,请使用ANSI-C引用,有关解决方法,请参见stackoverflow.com/questions/10748703/…

#1 楼

IFS代表“内部字段分隔符”。外壳使用它来确定如何进行单词拆分,即。 e。如何识别单词边界。 > IFS的默认值包含空格字符(准确地说是空格,制表符和换行符)。每个字符可以是一个单词边界。因此,使用默认值IFS,上面的循环将打印:

 Word: foo:bar
Word: baz
Word: rab
 


在换句话说,shell认为空白是一个单词边界。

现在,在执行循环之前尝试设置IFS=:。这次,结果是:

 Word: foo
Word: bar baz rab
 


现在,shell将mystring拆分为单词很好-但现在,它仅将冒号视为单词边界。可以从Advanced Bash脚本指南中获得,其中还可以找到有关特殊变量的更多信息):

mystring="foo:bar baz rab"
for word in $mystring; do
  echo "Word: $word"
done


比较至:

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z


请注意,在两个示例中,shell仍会将所有字符IFS$*:视为单词边界。唯一改变的是-的行为。

要知道的另一重要事项是如何处理所谓的“ IFS空白”。基本上,一旦;包含空格字符,就会在处理字符串之前从字符串中剥离前导和尾随空格以进行拆分,并且一系列连续的空格字符也将字段定界。但是,这仅适用于$*中实际存在的那些空白字符。

例如,让我们看一下字符串IFS(在IFS"a:b:: c d "之间追踪空格和两个空格字符)。空字符串)和c(同样,在dIFS=:之间有两个空格)。请注意最后一个字段中的前导和尾随空格。
使用"a",它将分为五个字段:"b"""" c d "(空字符串),cd

请注意第二个示例中多个连续的空白字符如何分隔两个字段,而多个连续的冒号不分隔(因为它们不是空白字符)。

对于IFS=' :'来说,"a""b"""和FreeBSD "c"也支持"d"语法(所有shell之间都有差异)。引用bash联机帮助页:


$'string'形式的单词经过特殊处理。该单词扩展为“字符串”,并按ANSI C标准的规定替换了反斜杠转义的字符。一个换行符。

评论


很好,但是,我认为,与bash脚本指南或其他内容相比,阅读和理解POSIX规范要好得多。基本上,在这样的链接上可用的信息缺少重要的方式。无论如何,因此错过了有关外壳拆分的两个关键点-globbing和IFS空白。

–mikeserv
2015年2月14日在16:43



@mikeserv谢谢,我在IFS空格上添加了一些信息。对此一无所知。 :)

– Tblue
15年2月14日在17:26

无关紧要,但是如果您感到好奇,则可能需要查看未设置的IFS如何使外壳的行为与IFS =完全不同。同样,IFS中的第一个字节也对“ $ {named_array [*]}”来说是特殊的-但在未引用扩展名时,这都无关紧要。

–mikeserv
2015年2月14日在17:30



3- $ readifest内置命令也使用$ IFS

–StéphaneChazelas
16年7月20日在14:15

@szx“ \ n”(或'\ n')与$'\ n'不同。第一个字符串由字符反斜杠和n组成。 $'\ n'产生一个换行符。为了获得最佳的可移植性,您不能使用$'\ n',因为只有某些shell支持它。将IFS设置为换行符的一种简便方法是IFS = $(printf'\ n。'); IFS = $ {IFS%。}(命令扩展会删除结尾的换行符,因此我们添加然后删除了另一个结尾的字符即可解决)。

– Tblue
20-11-29在18:35



#2 楼

在美元单引号内,某些字符会被特别评估。例如,将\n转换为新行。

因此,此特定行将新行分配给变量IFS。 IFS又是bash中的一个特殊变量:内部字段分隔符。正如man bash所说,它


用于扩展后的单词拆分,并使用read内置命令将行拆分为单词。默认值为<space><tab><newline>


评论


+1表示美元单引号,这与简单单引号不同。

–雪崩
18年2月13日在13:42

@Snowcrash +1表示+1美元表示单引号,这与简单的单引号不同。抱歉,无济于事:)但实际上,指出这一点非常好,因为它很重要!

–Pryftan
19年2月21日在17:09



@Pryftan +1表示+1表示+1 ...这很重要。

– 0xc0de
19年6月13日在10:44

@ 0xc0de绝对同意!感谢那! :)

–Pryftan
19年7月16日在21:26



#3 楼

简而言之,IFS=$'\n'将换行符\n分配给变量IFS

$'string'构造是一种引用机制,用于解码类似ANSI C的转义序列。此语法来自ksh93,并且可移植到现代外壳中,例如bashzshpdkshbusybox sh

#4 楼

我更喜欢通过示例来解释$IFS
您想对cp或mv或其他文件进行处理,IFS被defualt清空,当您的文件包含元字符或空格时,例如:您将拥有探针,因为:
Linux考虑一个单独的参数,而Administartion考虑一个单独的参数。所以bash具有Linux Administration.pdf,那么您可以初始化为Free Software Fundation.ogg,然后bash丢弃文件名之间的任何元字符和空格:

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS