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