次の名前のファイルがあります。
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.txt
S2
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
。内部ループは、現在のパターン文字列を使用して、現在のディレクトリ内のその文字列を含む名前を探します。非正規ファイル(ディレクトリ自体など)をスキップし、一致する他のすべてのコンテンツをそのパターン文字列に適したディレクトリに移動します。S3
S4
S1
S2
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で定義したタイプです。