次のエラーが発生します。
./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
${ ... }
(中括弧) 複数表示パラメータ拡張、最も簡単な方法は変数の値を拡張することです。コードの中かっこ内の内容は、有効なパラメータ名やその他の拡張ではないため、シェルは文句を言います。
構文が$( ... )
(一般括弧)であるコマンドの置換を望むようです。
また、少し不要なようです。変数はファイル名に展開され、渡さls
れます。ただ代わりに使うこともできます。ls $filename | sed...
ls
echo "$filename" | sed ...
つまり、シェルから直接次のように変更できます。
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
注意することができるため、バックスラッシュで引用する方がより正確になります。インスタンスに2つのコマンドを提供する.
こともできます。sed
sed -e 's/assemblyDB\.//' -e 's/\.las//'
それではfor filename in $(find . -type f -name "assemblyDB.*.las"); do
問題があります。lsを解析する主にファイル名のスペースとワイルドカードが原因で問題が発生します。 ksh/Bash/zsh では、シェルでフルループを実行できます。
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
ls
すでに指摘したように、これは(3行目、いいえ)と同じです。
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
今、for-iteratorの代わりにfind-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]の下にあるボタンを押します。 ]