运行 ${ls ... | 的错误替换 sed ...} 与 bash

use*_*828 7 bash

我收到以下错误:

./assemblyDB.116.las
test.sh: line 9: ${ls $filename | sed 's/assemblyDB.//' | sed 's/.las//'}: bad substitution
Run Code Online (Sandbox Code Playgroud)

这是脚本:

for filename in $(find . -type f -name "assemblyDB.*.las"); do
   echo $filename
   no=${ls $filename | sed 's/assemblyDB.//' | sed 's/.las//'}
   echo $no
done
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 22

${ ... }(花括号)标记了几种参数扩展,其中最简单的就是扩展变量的值。代码中大括号内的内容不是有效的参数名称或任何其他扩展,因此 shell 会抱怨。

您似乎想要命令替换,为此,语法是$( ... )(正则括号)。

此外,lsinls $filename | sed...似乎有点不必要,变量扩展为您的文件名,然后ls将其传递。你可以echo "$filename" | sed ...改用。

也就是说,您可以直接在 shell 中进行这些修改:

no="${filename/assemblyDB.}"   # remove first match
no="${no/.las}"
Run Code Online (Sandbox Code Playgroud)

或者,使用标准运算符:

no="${filename#assemblyDB.}"   # remove from start of string
no="${no%.las}"                # remove from end of string
Run Code Online (Sandbox Code Playgroud)

如果您运行sed,您可能需要注意.匹配正则表达式中的任何字符,因此用反斜杠引用它会更正确。你也可以给一个sed实例两个命令:sed -e 's/assemblyDB\.//' -e 's/\.las//'.

然后for filename in $(find . -type f -name "assemblyDB.*.las"); do解析 ls 的所有问题,主要是文件名中的空格和通配符会破坏它。在 ksh/Bash/zsh 中,你可以在 shell 中完成整个循环:

shopt -s globstar         # in Bash
for filename in **/assemblyDB.*.las; do
    ...
Run Code Online (Sandbox Code Playgroud)


小智 0

而不是${}使用反引号`[键盘上 Escape 下方的按钮。]

  • 您建议使用反引号。 (6认同)
  • 它们已经过时、难以阅读、不嵌套,并且可以**总是**被括号命令替换所替换。此外,在大多数 Markdown 语言中,它们很难放入内联代码块中:) (4认同)
  • @Jesse_b 有很多理由不使用反引号,但无法嵌套它们不是其中之一:```echo `echo \`echo hello\`` ```。是的,它需要转义,但这只是意味着它不像 `$(...)` 那样容易嵌套,并不是说它不可能。 (4认同)
  • 请不要使用反引号。使用命令替换。`$(...)` (3认同)