同じサフィックスを持つ複数のディレクトリを繰り返して、その中の特定のファイルに対して関数を実行するbashスクリプト(split.sh)を作成したいと思います。私はすぐに到着します:
#!/bin/bash
path="/mypath/MAP-9-[0-9][0-9][0-9]"
for filename in $path/*bam; do
[ -e "$filename" ] || continue
echo $filename
for chrom in `seq 1 22` X Y
do
samtools view -bh $filename $chrom > $path/$chrom.bam
samtools index > $path/$chrom.bam;
done
done
ただし、次のようなメッセージがたくさん表示されます。 "split.sh: line 12: /mypath/MAP-9-[0-9][0-9][0-9]/6.bam: No such file or Directory "
問題は、スクリプトがパス名の「[0-9] [0-9] [0-9]」正規表現部分を認識しないことです。また、角かっこ内にエスケープ文字を追加しようとしましたが、成功しませんでした。これは非常に簡単な解決策であるに違いありませんが、私はそれを理解することはできません。
以下はtreeコマンドの出力から抜粋したものです。
|-- [[
|-- MAP-9-001
| |-- MAP-9-001.bam
| `-- MAP-9-001.bam.bai
|-- MAP-9-003
| |-- MAP-9-003.bam
| `-- MAP-9-003.bam.bai
|-- MAP-9-005
| |-- MAP-9-095.bam
| `-- MAP-9-095.bam.bai
|-- split.sh
ベストアンサー1
glob
vs(ここで使用)regex
と混同しないでください。glob
Globは、文字列または拡張パス名を一致させるために使用できるシェルパターンです。
[[ $name = Bob* ]]
rm *.txt
バラよりhttp://mywiki.wooledge.org/glob
修正されたスクリプトバージョン:
#!/bin/bash
for filename in /path/MAP-9-[0-9][0-9][0-9]/*bam; do
[[ -e $filename ]] || continue
echo "$filename"
for chrom in {1..22} X Y; do
samtools view -bh "$filename" "$chrom" > "$(dirname "$filename")/$chrom.bam"
samtools index "$(dirname "$filename")/$chrom.bam"
done
done
シェルから正しく引用する方法を学ぶことは非常に重要です。
スペース/メタ文字を含むすべてのリテラルは「二重引用符」として扱われます。すべて拡張:
"$var"
、、、、。"$(command "$var")"
コードやテキストについてはを参照してください。"${array[@]}"
"a & b"
'single quotes'
$'s: 'Costs $5 US'
ssh host 'echo "$HOSTNAME"'
http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words
いつ二重引用符が必要ですか?
[[
[
コマンドに似ていますが、より強力なbashキーワードです。バラよりhttp://mywiki.wooledge.org/BashFAQ/031そしてhttp://mywiki.wooledge.org/BashGuide/TestsAndConditionals。 POSIX shに文章を書くのではないならオススメです。[[