ファイルの並べ替えとコピー

ファイルの並べ替えとコピー

私はここに初めて来ましたのでご了承ください。

何千ものファイルを含むディレクトリがあります。ファイル名は常に1〜2文字で始まり、その後にアンダースコア「_」の前に4文字が続きます。各モードのファイル数は異なる場合があり、ファイル名の下線の後の部分が変更されます。

サンプル:

Parentdir:
->AA01_*.pdf 
->AA01_*.html
->AA01_*.txt
...
->ZZ99_*.pdf
->ZZ99_*.html
->ZZ99_*.txt
...
->A001_*.pdf
->A001_*.html
->A001_*.txt
...
->Z999_*.pdf
->Z999_*.html
->Z999_*.txt

ファイル名の文字だけを使用して新しいディレクトリを作成し、その文字で始まるファイルで埋めるコマンドを実行したいと思います。ターゲットディレクトリに同じ名前のファイル(元のディレクトリの更新されたファイル)がある場合は、最新のファイルを保持したいと思います。だから:

New dir/files:
->AA
  AA01_*.pdf
  AA01_*.html
  AA01_*.txt
...
->ZZ
  ZZ99_*.pdf
  ZZ99_*.html
  ZZ99_*.txt
...
->A
  A001_*.pdf
  A001_*.html
  A001_*.txt
...
->Z
  Z999_*.pdf
  Z999_*.html
  Z999_*.txt

これは達成できますか?

ありがとうございます!

答え1

ファイルセットに移動します。文字プレフィックスを選択してください。ディレクトリを作成し(必要な場合)、ファイルをそのディレクトリに移動します。

#!/bin/sh
for item in *
do
    if [ -f "$item" ]
    then
        prefix="$(echo "$item" | sed 's/[^A-Z].*//')"
        echo mkdir -p "$prefix"
        echo mv "$item" "$prefix/"
    fi
done

echoプレフィックスを削除するmkdirと、mv満足のいくときに必要に応じて動作します。

答え2

使用真珠 renameユーティリティ(一部のLinuxディストリビューションではprenameとも呼ばれるfile-renameperl-rename

rename  -n  'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *

注: これはうまくいきますただPerl ベースの名前変更ユーティリティを使用します。rename -V(orprename -Vまたはor)を実行してインストールするかどうかfile-rename -Vを確認できますperl-rename -V。 perlまたはこれが言及されている場合、File::RenameこれはPerlのバージョンですrename。そうでなければ完全に異なる可能性がrenameありますutil-linux互換性がない機能とコマンドラインオプション。これはいいえutil-linuxの名前変更(または別のバージョンの名前変更 - it)を使用してください。必要パールの名前を変更する)

これは、一致する各ファイル名(欲張りではない一致)の最初の1つまたは2つの「単語」文字をディレクトリとして使用し、ディレクトリを作成し、ファイル名をディレクトリに置き換えます。 「単語」文字(\w)は次のように定義されますman perlre

「単語」文字の一致(英数字と「_」、その他の接続句読点とUnicodeマーカー)

これが望ましくない場合は、アルファベット文字や大文字のみを使用する[[:alpha:]]{1,2}?代わりにパターンを最適化できます。\w{1,2}?[[:upper:]]{1,2}

この\d番号。許可したい場合どの下線の前に文字を使用してください\w。または、[[:alnum:]]アルファベットと数字のみを許可するには、を使用します。

パターン全体と一致しないファイル名は影響を受けません。

注:-nオプションを使用すると、練習実行タスクが実行されます。内容のみが表示されます会議していますが、実際にはしません。要件を満たしていると確信している場合は削除します(または詳細な出力に-n置き換えます)。-v

たとえば、次の設定スクリプトがあるとします。

#!/bin/bash

for i in A AA Z9 ZZ  ; do
  for j in {01..10} ; do
    touch "$i${j}_.txt"
  done
done

# anomaly
touch A1001_.txt
$ ./setup.sh
$ ls
A01_.txt  A02_.txt  A03_.txt A04_.txt  A05_.txt  A06_.txt  A07_.txt  A08_.txt
A09_.txt A1001_.txt A10_.txt AA01_.txt AA02_.txt AA03_.txt AA04_.txt AA05_.txt
AA06_.txt AA07_.txt AA08_.txt AA09_.txt AA10_.txt setup.sh* Z901_.txt
Z902_.txt Z903_.txt Z904_.txt Z905_.txt Z906_.txt Z907_.txt Z908_.txt
Z909_.txt Z910_.txt ZZ01_.txt ZZ02_.txt ZZ03_.txt ZZ04_.txt ZZ05_.txt
ZZ06_.txt ZZ07_.txt ZZ08_.txt ZZ09_.txt ZZ10_.txt

Perlの名前変更スクリプトを実行した後:

$ rename 'if (m/^(\w{1,2}?)(\d{2,}_.*)/) {mkdir $1; $_ = "$1/$1$2"}' *
$ ls */*
A/A01_.txt   A/A02_.txt   A/A03_.txt   A/A04_.txt   A/A05_.txt A/A06_.txt
A/A07_.txt   A/A08_.txt   A/A09_.txt   A/A1001_.txt A/A10_.txt AA/AA01_.txt
AA/AA02_.txt AA/AA03_.txt AA/AA04_.txt AA/AA05_.txt AA/AA06_.txt
AA/AA07_.txt AA/AA08_.txt AA/AA09_.txt AA/AA10_.txt Z/Z901_.txt
Z/Z902_.txt  Z/Z903_.txt  Z/Z904_.txt  Z/Z905_.txt  Z/Z906_.txt  Z/Z907_.txt
Z/Z908_.txt  Z/Z909_.txt  Z/Z910_.txt ZZ/ZZ01_.txt ZZ/ZZ02_.txt ZZ/ZZ03_.txt
ZZ/ZZ04_.txt ZZ/ZZ05_.txt ZZ/ZZ06_.txt ZZ/ZZ07_.txt ZZ/ZZ08_.txt
ZZ/ZZ09_.txt ZZ/ZZ10_.txt

答え3

フォーラムへようこそ、ジカ様!

提案したいorganize- 忍耐力がある場合は、yaml特定の場所でファイルを検索し、名前を変更、移動、並べ替え、名前を付けることができるスクリプトを作成できます。私はそれを直接使用します。あなたがLinuxにどのように慣れているかはわかりませんが、Gitには必要なものすべてを非常に理解しやすい方法で説明するドキュメントがあります。

関連情報