错误:使用-r标志时“系统找不到指定的文件”

问题描述 投票:0回答:2

在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标志引起的。怎么修?

bash cygwin
2个回答
1
投票

好像你的版本sort不支持-r标志。你可以 ...

  • man sort搜索相同的选项。
  • 正常排序并使用另一个命令反转排序的输出,例如taccat的反面),或者如果不可用perl -e 'print reverse <>'。 示例:使用sort -r <<< "string"而不是sort <<< "string" | tac

另请参阅Glenn Jackman's Answer,了解脚本中可能存在的问题。


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[*]}"))

参考Simple Command Expansion,bash这样做:

  1. 它解析命令并查看IFS=somethingsorted=something,将其标记为变量赋值,将它们从命令行中取出
  2. 然后找不到任何其他作为命令执行,
  3. 然后,从左到右,在当前shell中分配这些变量 IFS设置为$'\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" !
© www.soinside.com 2019 - 2024. All rights reserved.