パターンマッチに基づいてファイルを移動する

パターンマッチに基づいてファイルを移動する

次の名前のファイルがあります。

XXXXX_S1_X_XX_X.txt
XXXXX_S2_X_XX_X.txt
XXXXX_S3_X_XX_XXX.txt
S4_X_XX_X.txt
XXXXX_S5_XX_X.txt   
...

S1、、、、S2...というS3フォルダのリストを作成しました。XXXXX_S1_X_XX_X.txtフォルダ内のファイル、S1フォルダ内のファイルなどを移動したいです。この単純なループを作成しましたが、そのフォルダ内のS *と一致するパターンに基づいてファイルをコピー/移動する方法がわかりません。XXXXX_S2_X_XX_X.txtS2

for i in My_list_of_folders.txt
do 
  dir=${i%.txt}
  mkdir "$dir"
  cp "$i" "$dir"
done

答え1

わずかに修正されたループ:

for pattern in S1 S2 S3 S4; do
   mkdir -p ./"$pattern"
   for filename in ./*"$pattern"*; do
       [ ! -f "$filename" ] && continue
       mv -i "$filename" "$pattern"/
   done
done

S1これにより、パターン文字列とが繰り返されますS2。内部ループは、現在のパターン文字列を使用して、現在のディレクトリ内のその文字列を含む名前を探します。非正規ファイル(ディレクトリ自体など)をスキップし、一致する他のすべてのコンテンツをそのパターン文字列に適したディレクトリに移動します。S3S4S1S2

slmがコメント(現在削除済み)で指摘したように、この場合、内部ループの操作は次のように短縮できます。

[ ! -f "$filename" ] || mv -i "$filename" "$pattern"/

または

[ -f "$filename" ] && mv -i "$filename" "$pattern"/

S1のようなパターンが重なっている場合は、S11まず長いパターンを作成する必要があります。

答え2

代わりに:

for i in S{4..1};do 
  mkdir -p $i
  while read line; do 
    [ -f "$line" ] && mv "$line" $i
  done < My_list_of_folders.txt
done

仕組み:

  • S{4..1}- シェル拡張を使用したディレクトリ名の構成
  • mkdir -p $i- 強制ディレクトリの作成
  • while read ... < My_list_of_folders.txt- ファイルの行を繰り返します。
  • [ -f "$line" ]...- 各ファイルを対応するSディレクトリに移動します。

メモ:ユースケースに適した範囲にglob({4..1})を調整できます。より大きなジョブを処理するためにS20....S1と重なる部分を処理するために逆順にソートするので、S{20..1}globで定義したタイプです。

関連情報