Причина этой ошибки в том, что {$ str7DaysAgo .. $ strPrevDay}
сначала раскрывает фигурные скобки (что ничего не делает, так как это не имеет формы { НОМЕР1 .. НОМЕР2 }
), а затем раскрывает переменные. Это ловушка.
Для 7 дней вполне разумно перечислить дни с датой
. См. ответ Джеффа Шаллера .
Другой вариант - использовать eval
для принудительного выполнения вычислений в желаемом порядке. Использование eval
подвержено ошибкам, так как вам нужно быть очень осторожным с частями, которые оцениваются дважды, но здесь у нас есть части имен файлов, которые, как известно, содержат только цифры, так что это нормально. Обратите внимание, что вам нужно включить nullglob
опцию на случай, если бывают дни, когда файл не создается.
#!/bin/bash
last_day=$(date +"%Y%m%d" -d "yesterday")
first_day=$(date +"%Y%m%d" -d "7 days ago")
eval "all_days=({$first_day..$last_day})"
image_directory=~/Documents/Projects/Radar/Images/
temporary_directory="$image_directory/Temp/"
filename_prefix="foo_"
shopt -s nullglob
for day in "${all_days[@]}"; do
files=("$image_directory/$filename_prefix$day"*.gif)
if [[ ${#files[@]} != 0 ]]; then
cp "${files[@]}" "$temporary_directory"
fi
done
(Я также исправил ваше цитирование - и ваши трудночитаемые имена переменных. Обратите внимание, что VAR = "~ / something"
ставит тильду в VAR
, вам необходимо оставьте тильду без кавычек, чтобы получить домашний каталог. Затем Bash разворачивает тильду, потому что у вас было расширение переменных без кавычек, которое сломалось бы, если имена каталогов содержали пробелы или другие специальные символы оболочки - не оставляйте переменные без кавычек, если вы не знаете, что это необходимо .)
Альтернативный подход - перечислить файлы и скопировать только те, которые находятся в желаемом диапазоне. Это, вероятно, будет быстрее для больших диапазонов, потому что каждое использование подстановочного знака должно перечислять файлы в каталоге (более быстрого способа получить файлы, соответствующие определенному шаблону).
#!/bin/bash
last_day=$(date +"%Y%m%d" -d "yesterday")
first_day=$(date +"%Y%m%d" -d "7 days ago")
image_directory=~/Documents/Projects/Radar/Images/
temporary_directory="$image_directory/Temp/"
filename_prefix="foo_"
shopt -s nullglob
for file in "$image_directory/$filename_prefix"*.gif; do
file_date="${file##*/"$filename_prefix"}"; file_date=${file_date:0:8}
if ((file_date >= first_day && file_date <= last_day)); then
cp "$file" "$temporary_directory"
fi
done
Попробуйте это:
tree | sed '/\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 image\.[0-9]\+\.jpg/d; s/\(\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 image\.\)[0-9]\+\(\.jpg\)/\1####\2/'
/.../d;
удаляет все строки, содержащие├── image.[0-9]+.jpg
(псевдо--шаблон )записи s/.../\1####\2/
заменяет последнюю строку└── image.[0-9]+.jpg
Выход:
$ tree | sed '/\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 image\.[0-9]\+\.jpg/d; s/\(\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 ima
ge\.\)[0-9]\+\(\.jpg\)/\1####\2/'
.
├── directory1
│ └── image_sequence
│ └── image.####.jpg
└── directory2
├── someanotherfile.ext
└── somefile.ext
3 directories, 8 files
Это, конечно, будет работать только в том случае, если все файлы в image_sequence
соответствуют шаблону изображения и изменят имена файлов в других каталогах, соответствующих шаблонам. Например, если последним файлом в image_sequence
является readme.txt
, вместо этого вы удалите все записи изображений.
Вы можете заменить числовые части последовательных имен файлов на #
s, используя выражение sed
(, подобное второму в ответе Фредди). uniq
может затем удалить повторяющиеся строки:
tree | sed 's/\.[0-9]\+\.jpg/.####.jpg/g' | uniq
Это по-прежнему оставит две записи для изображений (, поскольку в последней строке используется другой символ в дереве -части рисунка ), но список по-прежнему обрезан до приемлемой длины:
.
|-- directory1
| `-- image_sequence
| |-- image.####.jpg
| `-- image.####.jpg
`-- directory2
|-- someanotherfile.ext2
`-- somefile.ext