在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
标志引起的。如何解决?
答案 0 :(得分:1)
我不认为像这样干扰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[*]}"))
bash引用Simple Command Expansion:
IFS=something
和sorted=something
,将它们标记为变量分配,将其从命令行中删除$'\r\n
"${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" !
答案 1 :(得分:1)
似乎您的sort
版本不支持-r
标志。你可以...
man sort
中搜索等效选项。tac
(与cat
相反)或如果perl -e 'print reverse <>'
不可用,则反转排序的输出。sort -r <<< "string"
代替sort <<< "string" | tac
。也请查看Glenn Jackman's Answer有关脚本中可能存在的问题。