サブディレクトリを抽出し、パスの一致するパターンに基づいてシンボリックリンクを作成します。

サブディレクトリを抽出し、パスの一致するパターンに基づいてシンボリックリンクを作成します。

私はファイルを抽出するためにパスを使用しますfind。パスコマンドfindは次のとおりです。

tmp=$(find $Some_Dir -name "*.gz")

出力は次のとおりです

echo "$tmp"

/xxxx/abc/bcd/def/something/ZRT834/ZRT834_9/5678/S1_L001_R1.gz /xx/abc/bcd/def/ddd/ZRT834/ZRT834_9/5678/S2_L001_I1.gz /abc/bcd/def/ZRT834/ZRT834_9/5678/S1_L001_I2.gz /abc/bcd/def/ZRT207/ZRT207_1/5678/S1_L001_R1.gz /abc/bcd/def/hfgdh/ZRT207/ZRT207_1/5678/S1_L001_R2.gz /abc/bcd/def/ZRT207/ZRT207_1/5678/S1_L001_I2.gz /sgdj/hbsdj/ldnc/jnjdss/ZRT102_9/S5_L002_I1.gz

サブディレクトリを作成し、一致するパターンに基づいてシンボリックリンクを作成したいと思います。たとえば、各パスでZRT開始および終了するパターンを一致させ、_somenumber存在しない場合は、そのパス要素でサブディレクトリを作成しようとします。次に、ファイルへのシンボリックリンクを.gzそのディレクトリに作成します。

出力は次のようになります。などのZRT834_9シンボリックリンクがあるディレクトリです。S1_L001_R1.gzS2_L001_I1.gzS1_L001_I2.gz

編集:これは私の元の質問です。また、以前はあまり複雑でない質問を投稿しました。ここ

答え1

についてtmp=$(find $Some_Dir -name "*.gz")

  1. 常にシェル変数を引用してください(例:"$Some_Dir"、と同様$Some_Dir)。https://mywiki.wooledge.org/Quotes
  2. ファイル名をスカラー変数として読み取るのではなく、そうすることでファイル名のスペースを処理するのが難しくなるため、配列に読み込んでください。

したがって、次のようにする必要があります。

readarray -d '' files < <(find "$Some_Dir" -type f -name '*.gz' -print0)

これで、次のようにファイルを繰り返して目的の操作を実行できますI want to match the pattern starting with ZRT and ending with _somenumber

re='ZRT.*_somenumber'
for file in "${files[@]}"; do
    if [[ $file =~ $re ]]; then
        do whatever you like
    fi
done

明らかに、最初はファイルの配列は必要なく、次の出力を繰り返すことができますfind

re='ZRT.*_somenumber'
while IFS= read -r -d '' file; do
    if [[ $file =~ $re ]]; then
        do whatever you like
    fi
done < <(find "$Some_Dir" -type f -name '*.gz' -print0)

答え2

ファイルの検索中にすぐにこれを行うことができます。

find Dir/ -name '*.gz' -regex '.*/ZRT[^/]*_[0-9]+/.*' -exec \
bash -c ': "$(grep -o "/ZRT[^/]*_[0-9]\+/" <<<"$0")";\
mkdir -p "${_#/}"; ln -s "$0" "${_#/}"' {} \;

関連情報