У меня есть folderA, у которого есть некоторые файлы с последовательностью чисел, начиная с a_000000. Я хочу, чтобы удалить файлы, начиная с определенного номера: допустим, a_000750 до конца файлов в этом folderA. Может ли кто-нибудь посоветует, как это сделать, используя сценарий оболочки?
Вы можете сделать что-то вроде этого:
find . -regextype posix-extended -iregex './a_[0-9]{6}' -execdir bash -c '[[ ${1##./a_} > 000750 ]] && echo $1' "removing: " {} \;
Или:
find . -regextype posix-extended -iregex './a_[0-9]{6}' | sort | sed '0,/000750/d' | xargs echo
Первый метод предполагает фиксированный префикс, отключает его и проверяет значение.
Второй метод предполагает суффикс фиксированной длины (и общий фиксированный префикс) и полагается на этот факт; и что, в то время как 201 предшествует 31 в лексикографическом плане, это не до 031.
Проверьте это с помощью команды echo, и как только вы убедитесь, что она перечисляет верните файлы, используйте rm вместо этого.
Первое решение terdon основывается на расширении скобки, которое является свойством bash и ksh, однако оно не может использоваться в стандартной оболочке /bin/sh, которая на Ubuntu обозначается символом /bin/dash.
В случаях, когда вам приходится полагаться /bin/sh на переносимость ваших сценариев, есть два способа приблизиться к этому. Один из них был бы через глобус. Просто cd folderA и оттуда бегут rm a_*. Другим способом было бы реализовать альтернативу C-style для цикла с использованием while <CONDITION>;do ...done в языке оболочки и форматировать числа с помощью printf:
$ sh -c 'i=0;while [ $i -le 750 ]; do filename=$(printf "a_%06d" $i);echo "$filename";i=$((i+1)) ;done'
Обратите внимание, что здесь я использую echo. Замените echo "$filename" на rm ./"$filename" или rm -- "$filename", когда вы будете готовы удалить файлы. Также обратите внимание, что это должно выполняться, когда вы уже cd вышли в нужный каталог.
Awk, являющийся хорошим C-подобным языком, может помочь нам двумя способами: (1) мы можем сгенерировать имена файлов с помощью for-loop и отформатировать их с помощью функции sprintf и (2) удалить указанные файлы с помощью команды system(), которая передаст наше сгенерированное имя файла и rm в [ f21]:
awk 'BEGIN{for(i=0;i<=750;i++){filename=sprintf("a_%06d",i);system("rm "filename);} }'
Продолжая идею портативного подхода, где мы «сгенерируем» имена файлов, мы можем сделать то же самое в Perl:
perl -le 'for(0..750){$fd=sprintf("a_%06d",$_);unlink($fd)}'