我收到以下错误:
./assemblyDB.116.las
test.sh: line 9: ${ls $filename | sed 's/assemblyDB.//' | sed 's/.las//'}: bad substitution
这是脚本:
for filename in $(find . -type f -name "assemblyDB.*.las"); do
echo $filename
no=${ls $filename | sed 's/assemblyDB.//' | sed 's/.las//'}
echo $no
done
答案1
${ ... }
(花括号)标记了几种参数扩展,其中最简单的就是扩展变量的值。代码中大括号内的内容不是有效的参数名称或任何其他扩展,因此 shell 会抱怨。
您似乎想要命令替换,为此,语法是$( ... )
(正则括号)。
另外,ls
inls $filename | sed...
似乎有点不必要,变量扩展为您的文件名,然后ls
将其传递。你可以直接用它echo "$filename" | sed ...
来代替。
也就是说,您可以直接在 shell 中进行这些修改:
no="${filename/assemblyDB.}" # remove first match
no="${no/.las}"
或者,使用标准运算符:
no="${filename#assemblyDB.}" # remove from start of string
no="${no%.las}" # remove from end of string
如果您确实运行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
...
答案2
命令替换(第 3 行)
for filename in $(find . -type f -name "assemblyDB.*.las"); do
echo $filename
no=$(ls $filename | sed 's/assemblyDB.//' | sed 's/.las//')
echo $no
done
正如已经指出的那样,相当于(第 3 行,否ls
)
for filename in $(find . -type f -name "assemblyDB.*.las"); do
echo $filename
no=$(echo $filename | sed 's/assemblyDB.//' | sed 's/.las//')
echo $no
done
或更短(第 4 行消失,现在直接回显)
for filename in $(find . -type f -name "assemblyDB.*.las"); do
echo $filename
echo $filename | sed 's/assemblyDB.//' | sed 's/.las//'
done
sed 命令可以简化为(第 3 行)
for filename in $(find . -type f -name "assemblyDB.*.las"); do
echo $filename
echo $filename | sed 's/assemblyDB.//;s/.las//'
done
或者用 sed 提取中间部分:(仍然是第 3 行)
for filename in $(find . -type f -name "assemblyDB.*.las"); do
echo $filename
echo $filename | sed -r 's/.*assemblyDB.(.*).las/\1/'"
done
现在 find-iterator 而不是 for-iterator:(第 1 到 3、4 行消失了)
find . -type f -name "assemblyDB.*.las" -printf "%f\n" -exec sh -c "
echo {} | sed -r 's/.*assemblyDB.(.*).las/\1/'" ";"
assemblyDB.11.las
11
assemblyDB.9.las
9
assemblyDB.10.las
10
如果您的文件名采用这样或类似的顺序,则以下方法也可能有效:
for i in {8..12} ; do ls assemblyDB.$i.las && echo $i ; done 2>/dev/null
assemblyDB.9.las
9
assemblyDB.10.las
10
assemblyDB.11.las
11
(包括 8 和 12,以演示序列中丢失的文件)。
答案3
而不是${}
使用反引号`
[键盘上 Escape 下方的按钮。]