Как пакетно организовать файлы?

У меня есть каталог с гигабайтами (около 8 ГБ) небольших отдельных файлов. Я хочу организовать их в каталогах по дате. Дата его создания является частью имени файла.

Вот пример имени файла:

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

Я хочу настроить каталог документов следующим образом:

docs_by_date
    2013
        01
        02
        03
        04

Если каталог назначения не существует, его следует создать. После проверки успешной копии исходный файл должен быть удален.

Я не супер гуру с bash, многие символы я до сих пор не знаю, что они означают, поэтому было бы здорово объяснить, что делает сценарий.

3
задан 14 August 2013 в 13:32

2 ответа

Я сделал предположение, что для файла 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 чище, чем копирование и удаление в любом случае. Одна из причин заключается в том, что cp не имеет контрольной суммы, хотя вместо этого можно использовать rsync -a.

0
ответ дан 14 August 2013 в 13:32

Хорошо, похоже, я понял это благодаря твоей помощи!

Это была простая ошибка! Есть 7 полей вместо 6! Если вы посмотрите исходное имя файла:

4RCPBlockCoverLtrednalaserfalse 07 -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}/"
done

«,» между {1,3} было ключевым для меня лично.

и "/" в конце строки cp $ {month} / "также были ключевыми.

0
ответ дан 14 August 2013 в 13:32

Другие вопросы по тегам:

Похожие вопросы: