在Windows XP上使用cygwin bash。 Bash版本:4.3.46(7) - 发布。最小的工作示例,以相反的顺序排序数组:
#!/bin/bash
array=("a c" b f "3 5")
IFS=$'\r\n' sorted=($(sort -r <<<"${array[*]}"))
printf "[%s]\n" "${sorted[@]}"
cygwin出错:
-rThe system cannot find the file specified.
在Linux上运行正常。该错误是由-r
标志引起的。怎么修?
好像你的版本sort
不支持-r
标志。你可以 ...
man sort
搜索相同的选项。tac
(cat
的反面),或者如果不可用perl -e 'print reverse <>'
。
示例:使用sort -r <<< "string"
而不是sort <<< "string" | tac
。另请参阅Glenn Jackman's Answer,了解脚本中可能存在的问题。
我不认为像这样搞乱IFS会给你你想要的结果。试试这个:
#!/bin/bash
array=("a c" b f "3 5")
readarray -t sorted < <(printf "%s\n" "${array[@]}" | sort -r)
printf "[%s]\n" "${sorted[@]}"
哪个输出
[f]
[b]
[a c]
[3 5]
我认为你的困难在于:
IFS=$'\r\n' sorted=($(sort -r <<<"${array[*]}"))
参考Simple Command Expansion,bash这样做:
IFS=something
和sorted=something
,将其标记为变量赋值,将它们从命令行中取出$'\r\n
在处理已排序的赋值时,bash执行其扩展:
命令替换执行:
"${array[*]}"
扩展为字符串a c\rb\rf\r3 5
,因为[*]
参数扩展使用$ IFS的第一个字符连接数组元素。
sort -r <<<$'a c\rb\rf\r3 5'
,因为它给出了一行输入,返回输入不变。
现在我们有sorted=($'a c\rb\rf\r3 5')
,并且由于命令替换是不加引号的,因此会发生单词拆分:使用IFS的字符作为分隔符拆分字符串
所以我们最终得到的sorted=("a c" b f "3 5")
恰好与原始数组具有相同的顺序。我对你脚本的行结尾的评论:
当脚本文件具有DOS样式的CRLF行结尾时,第一行被bash视为
array=("a c" b f "3 5")$'\r'
这意味着array
不是一个数组,而是一个值:
$ IFS=$' \t\n' # the default value
$ array=("a c" b f "3 5")$'\r'
$ declare -p array
"eclare -- array="(a c b f 3 5)
# ......^^ _not_ "-a" !