私はファイルを抽出するためにパスを使用します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.gz
S2_L001_I1.gz
S1_L001_I2.gz
編集:これは私の元の質問です。また、以前はあまり複雑でない質問を投稿しました。ここ。
答え1
についてtmp=$(find $Some_Dir -name "*.gz")
:
- 常にシェル変数を引用してください(例:
"$Some_Dir"
、と同様$Some_Dir
)。https://mywiki.wooledge.org/Quotes。 - ファイル名をスカラー変数として読み取るのではなく、そうすることでファイル名のスペースを処理するのが難しくなるため、配列に読み込んでください。
したがって、次のようにする必要があります。
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" "${_#/}"' {} \;