копировать огромное количество файлов в структурированный по дате каталог

копировать огромное количество файлов в структурированный по дате каталог

Мне нужно скопировать около 40.0000 файлов в папки, структурированные по дате.
Пример файла:

/var/public/voicelogging/quality_monitoring/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

Один из многих файлов, которые мне нужно скопировать/home/username/logging/

В имени файла есть 2 переменные, которые мне нужно использовать:

bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

20151209Конечно, дата
12434— это идентификатор пользователя, создавшего файл.

Мне нужен скрипт/однострочный код, который может искать в каталоге идентификатор пользователя.

Затем создайте каталог с идентификатором пользователя в /home/username/logging. После того, как он создал папку, ему нужно создать каталог для каждой даты, которую он сможет найти.
И поместить каждый файл в нужный userid/dateкаталог.
пример результирующего каталога.

/home/username/logging/12434/20151209/bbbbbb_I_20151209-185841_xxxxxx_12434_89343.WAV

Я создал однострочный код для создания каталога дат, но мне все еще нужно самому создать каталог идентификаторов пользователей.

find /var/public/voicelogging/quality_monitoring/ -type f -name "*12434*" | sed -r 's/^.{65}//' | cut -c1-8 | xargs -I {} mkdir {} /home/username/logging/12434

Как скопировать нужный файл в нужное место?

решение1

Один способ с findи install:

find /var/public/voicelogging/quality_monitoring -name \*.WAV -exec sh -c '
bn=${0##*/}; x=${bn%%-*}; dt=${x##*_}; y=${bn%_*}; id=${y##*_} 
install -D "$0" "/home/username/logging/${id}/${dt}/${bn}"' {} \;

здесь используется расширение параметра для извлечения даты: ${dt}и идентификатора пользователя: ${id}из имени файла, а затем используетсяinstallскопировать каждый файл в соответствующий userID/dateкаталог (это потому что я ленивый) - без installзамены последней строки на:

dest=/home/username/logging/${id}/${dt}; mkdir -p "${dest}" && cp "$0" "${dest}"' {} \;

Если вы предпочитаете пройтись по этим каталогам «дата», а затем пройтись по .WAVфайлам в каждом каталоге:

for d in /var/public/voicelogging/quality_monitoring/*; do
  dt=${d##*/}
  for f in $d/*.WAV; do
    bn=${f##*/}; y=${bn%_*}; id=${y##*_}
    dest=/home/username/logging/${id}/${dt}
    mkdir -p "${dest}" && cp "${f}" "${dest}"
  done
done

Если у вас есть, zshто это проще и короче zmv(также потому, zshчто это умнее и вы можете вкладывать переменные расширения, например, ${${file%_*}##*_}будет достаточно извлечь идентификатор пользователя):

dtcp () {                                                                     
mkdir -p $3 && cp $1 $2 $3
}
autoload zmv
zmv -n -p dtcp '/var/public/voicelogging/quality_monitoring/(*)/(*).WAV' \
'/home/username/logging/${${2%_*}##*_}/$1'

S (*)создает обратные ссылки, которые можно использовать во втором параметре как $1и $2т. д.
Здесь zmvwith -pвыполняет функцию dtcpвместо mv. Функция создает каталог, а затем копирует файл в недавно созданный каталог. Аргументы (не путать с обратными ссылками выше):
$1: --
что означает конец опций
$2: /var/public/voicelogging/quality_monitoring/(*)/(*).WAV'
это файл, который нужно скопировать и
$3: /home/username/logging/${${2%_*}##*_}/$1
это место назначения
Примечание, которое -nобозначаетпробный прогон; удалите его, чтобы выполнить команду.

Связанный контент