web-dev-qa-db-ja.com

ファイルをまとめて整理する方法は?

小さな個別ファイルのギガバイト(約8 GB)のディレクトリがあります。日付順にディレクトリに整理したい。作成日はファイル名の一部です。

次にファイル名の例を示します。

4RCPBlockCoverLtrednalaserfalse07-10-2012-11-50-14-656.doc.gz

次のようなdocsディレクトリのセットアップが必要です。

docs_by_date
    2013
        01
        02
        03
        04

宛先ディレクトリーが存在しない場合は、作成する必要があります。コピーが成功したことを確認したら、ソースファイルを削除する必要があります。

私はbashの専門家ではありません。多くの記号がまだ何を意味するのかわからないので、スクリプトが何をしているのかを説明するのはすばらしいでしょう。

3
Mike De

ファイル07-10-2012-11-50-14-656.doc.gz、年で並べ替えます(つまり、2012)と月(つまり10)。

#!/usr/bin/env bash
# This is the preferred way of invoking a bash script, and is better than #!/bin/bash for reasons of portability.
# To use the script, make it executable with `chmod u+x /path/to/script`
# Then run this script with `/path/to/script /path/to/original/files /path/to/docs_by_date`

# Let's set up some path variables. This script will transfer files from the directory specified by the first argument to the directory specified by the second.
pathtooriginalfiles=$1
pathtotarget=$2

# Lets iterate over the files in the original directory, by listing all non-invisible files with $(ls ${pathtooriginalfiles}), and repeating the block with $i changing each time.
for i in $(ls "${pathtooriginalfiles}"); do
  # Find the matching parts of the filename that specify the date by echoing then piping the variable to sed. The regex part looks for "everything at the beginning" ^.*, followed by two iterations of digits [0-9]{2}, followed by four iterations of digits, etc. before ending with .doc.gz. It then replaces this entire string with what matches between () using the \1 variable, i.e. the year or month.
  year=$(echo -n ${i}| sed -r 's/^.*[0-9]{2}-([0-9]{4})-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{3}\.doc\.gz$/\1/')
  month=$(echo -n ${i}| sed -r 's/^.*([0-9]{2})-[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}-[0-9]{3}\.doc\.gz$/\1/')

  # Create the directory if it doesn't exist already, then copy into it.
  mkdir -p "${pathtotarget}/${year}/${month}"
  cp "${pathtooriginalfiles}/${i}" "${pathtotarget}/${year}/${month}"
done

また、私はあなたが要求したものを正確にコード化していません。あなたはそれがファイルがそこにあるかどうかを確認するためにテストし、その後それらを自動的に削除するべきだと言った。代わりに、このスクリプトはそれらをコピーし、オリジナルをそのままにします。スクリプト自体に依存するのではなく、手動で「テスト」して、想定どおりに機能することを確認することをお勧めします。 (コピー部分のバグはおそらくチェック部分に複製されます。)スクリプトで本当にオリジナルを削除したい場合は、代わりにcp部分をmvに変更してください。 (とにかくmvはコピーや削除よりもクリーンだと思います。1つの理由は、cpがチェックサムを実行しないことですが、rsync -a代わりに。

3
Sparhawk

わかりました、あなたの助けにより、私はそれを理解したように見えます!

単純なエラーでした! 6つのフィールドではなく、7つのフィールドがあります。元のファイル名を見ると:

4RCPBlockCoverLtrednalaserfalse 7-10 -2012-11-50-14-656.doc.gz

  • 太字のセクションが目的です。年(2012)と月(7)。スクリプトでは、10(07と2012の間)を最初のフィールドとして扱いました。私がしたことは、それらと出来上がりの間に[0-9] {2}を追加することだけでした。

これはあなたが私に与えたスクリプトであり、それから私がそれをどのように「編集」したかを見ることができます。

どうもありがとうございました!私の日を救った!

#!/ usr/bin/env bash 
 pathtooriginalfiles = $ 1 
 pathtotarget = $ 2 
 
 for i in $(ls "$ {pathtooriginalfiles } "); do 
 
 year = $(echo -n $ {i} | sed -r 's /^.* [0-9] {2}-[0-9] {2}- ([0-9] {4})-[0-9] {2}-[0-9] {2}-[0-9] {2}-[0-9] {1,3} \。 doc\.gz $/\ 1 /')
 month = $(echo -n $ {i} | sed -r 's /^.*([0-9] {2})-[0 -9] {2}-[0-9] {4}-[0-9] {2}-[0-9] {2}-[0-9] {2}-[0-9] {1 、3} \。doc\.gz $/\ 1 /')

 echo $ year $ month 
 mkdir -p "$ {pathtotarget}/$ {year}/$ {month} "
 ls -l $ pathtotarget 
 cp -auv" $ {pathtooriginalfiles}/$ {i} "" $ {pathtotarget}/$ {year}/$ {month}/「
完了

個人的には、{1,3}の間の「、」がキーでした。

また、cp文字列$ {month} /の末尾の「/」も重要でした。

0
Mike De