Unix。パス名に正規表現を含む特定のファイルに対して複数のディレクトリでスクリプトを実行する

Unix。パス名に正規表現を含む特定のファイルに対して複数のディレクトリでスクリプトを実行する

同じサフィックスを持つ複数のディレクトリを繰り返して、その中の特定のファイルに対して関数を実行する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

globvs(ここで使用)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に文章を書くのではないならオススメです。[[

おすすめ記事