日付を含むファイルを保存するためにサブディレクトリを作成するのに役立ちます。 [閉じる]

日付を含むファイルを保存するためにサブディレクトリを作成するのに役立ちます。 [閉じる]

これはこのフォーラムの新しいものですが、RHELやスクリプトに慣れていません。ところでこれがちょっと気になりますね。次のファイルがあります。

2019-05-01-00.34.00.msg 
2019-05-02-00.36.00.msg
2019-06-14-01.38.00.msg

次のディレクトリに保存したいと思います。

/2019/05/01/<Filename>
/2019/05/02/<Filename>
/2019/06/14/<Filename>

また、ディレクトリに入れるときに現在のファイル名を保持したいと思います。また、bashを使用してこれを実行したいと思います。

どんなアイデアがありますか?

答え1

名前を繰り返し、名前を分割して-からmkdir -p存在しない場合は、ディレクトリを作成して最後に移動できます。このような:

for file in *msg; do 
    IFS="-" read -r year month day rest  <<< "$file"
    dir="$year/$month/$day/" 
    mkdir -p -- "$dir"
    mv -- "$file" "$dir"
done

答え2

これはPerlの名前変更ツール(いいえutil-linuxパッケージの名前変更ツール)。例えば

設定:

$ touch 2019-05-01-00.34.00.msg 2019-05-02-00.36.00.msg 2019-06-14-01.38.00.msg
$ ls -l
total 2
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-05-01-00.34.00.msg
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-05-02-00.36.00.msg
-rw-r--r-- 1 cas cas 0 Oct 16 20:56 2019-06-14-01.38.00.msg

名前を変更してください:

rename  -n '
  use File::Path qw(make_path);

  if (-f $_ && m/^\d{4}-\d{2}-\d{2}-/) {
    my ($y,$m,$d,$f) = split /-/,$_,4;
    make_path("$y/$m/$d");
    $_ = "$y/$m/$d/$f";
  }' *.msg

スクリプトは最初に非正規ファイル(-f)またはパターンと一致しないファイル名を無視します^YYYY-MM-DD-。これにより、ジャンク入力が提供されたときに不要なディレクトリが生成されるのを防ぎます。

ファイル名を4つの要素に分割します。最初の3つはファイル名に含まれる年月日($y、、)で、4番目はファイル名の残りの部分($m)です。$d$f

make_path()次の機能を使用してください。ファイルパスYYYY/YYYY/MM/、およびのディレクトリを繰り返し生成するための標準モジュールです(コマンドのオプションYYYY/MM/DD/に似ています)。 Perl機能を3回実行することもできましたが。-pmkdirmkdir()File::Path

$_次に、同じを設定してファイル名を正しいディレクトリに変更(つまり移動)します。"$y/$m/$d/$f"

これがPerlがどのように機能するかという鍵ですrename。あなたはそれを使用することができますどのs/foo/bar/単純な検索と置換スタイルから、この回答にあるよりもはるかに複雑なスクリプトまで、Perlコード。コードが変更されると、$_ファイル名が変更されます。変更しないと$_名前は変わりません。

注:この行は「オプションrename-nを使用するため、試運転ただ。実際にファイル名を変更するには、ファイルを削除するか、次のように詳細な出力に-n変更します。-v

2019-05-01-00.34.00.msg renamed as 2019/05/01/00.34.00.msg
2019-05-02-00.36.00.msg renamed as 2019/05/02/00.36.00.msg
2019-06-14-01.38.00.msg renamed as 2019/06/14/01.38.00.msg

ちなみに、ファイル名は上記のようにコマンドラインに渡すか、スクリプトにパイプすることができます(たとえば、NULで区切られたリストを出力するための別の入力ファイル名を受け入れるオプションがあります)rename-0find ... -print0

最後にrename追加してください。いいえ-fakaオプションを使用するように指示しない限り、既存のファイルを上書きします--force

関連情報