Основное недоразумение здесь, по-видимому, заключается в том, что изменение символической ссылки во время ее записи изменит что-либо ожидаемым образом.
Нет. Как только будет открыт фактический файл (, устройство или канал ), все действия будут относиться к открытому файлу, игнорируя все, что происходит, например, с символической ссылкой, указывающей на него. На самом деле, это не ограничивается символическими ссылками, но в равной степени относится и к «жестким» ссылкам, которые вообще заставляют файлы иметь имена :. В unixoid-системах вы можете перемещать или даже удалять (! )файл (НЕ :Перезаписывать! )что какой-то процесс был открыт, и процесс не увидит никаких изменений, пока не закроет файл.
Вот мое предложение, если я правильно понял:
for i in *.nc; do
[[ "$i" =~ _([0-9]{8})[_.] ]] && d="${BASH_REMATCH[1]}"
mkdir -p "${d:0:4}/${d:4:2}"
mv "$i" "${d:0:4}/${d:4:2}"
done
Предполагая, что дата всегда находится в одном и том же месте в имени файла, поместите это в скрипт:
#!/bin/bash
#
while $# -gt 0 ; do
file="$1"
shift
year="$( echo "$file" | cut -c 14-17)"
mnth="$( echo "$file" | cut -c 18-19)"
[[ -d $year/$mnth ]] || mkdir -p $year/$mnth
echo mv "$file" $year/$mnth
done
И вызовите скрипт с помощью:
find. -maxdepth 1 -type f -name '*201*' -printf | \
xargs -r the_script
Прочитать man bash find xargs mkdir mv
.
Удалите echo
, если хотите сделать это по-настоящему.
Цикл по годам и месяцам:
#!/bin/bash
for year in {2001..2020} ; do
mkdir $year
for month in {01..12} ; do
mkdir $year/$month
mv gpm_cressman_${year}${month}* $year/$month
done
done
Если у вас слишком много файлов с длинными именами в год и месяц (, вы утверждаете, что «тысячи» ), bash
могут достичь своего предела («слишком длинный список аргументов» ). Либо временно увеличьте ulimit , либо используйтеxargs
:
#!/bin/bash
for year in {2001..2020} ; do
mkdir $year
for month in {01..12} ; do
mkdir $year/$month
find -maxdepth 1 -type f -name "gpm_cressman_${year}${month}*" |
xargs -I '{}' mv '{}' $year/$month
done
done