У меня folderA
есть некоторые файлы с последовательностью номеров, начиная с a_000000
. Что я хочу сделать, это удалить файлы, начиная с определенного числа: скажем, a_000750
до конца файлов в этом folderA
. Может кто-нибудь, пожалуйста, посоветуйте, как это сделать с помощью сценария оболочки?
16
rm a_000[89]* a_0007[5-9]*
?a_000[89]*
включает каждый файл, начинающийся сa_0008
илиa_0009
, иa_0007[5-9]*
включает каждый файл, начинающийся с,a_0007
а затем содержащий число от 5 до 9, за которым следует что-либо.Ответы:
Предполагая, что вы знаете или можете угадать конец диапазона, вы можете использовать скобки :
Приведенное выше удалит 101 файл в диапазоне от a_000750 до a_000850 включительно (и пожалуется на имена файлов, которые ссылаются на несуществующие файлы). Если у вас слишком много файлов для этого, используйте
find
:Здесь
find
просто перечислены все файлы, соответствующиеa_*
. Список передается вwhile
цикл, где каждое имя файла считывается в переменную$file
. Затем, используя возможности bash для работы со строками , если числовая часть (find печатает файлы как./file
, а значит${file#./a_}
печатает только номер)000750
больше или больше, файл удаляется. Это-v
просто там, чтобы вы могли видеть, какие файлы были удалены.Обратите внимание, что приведенное выше предполагает нормальные имена файлов. Если ваши имена могут содержать пробелы, символы новой строки или другие странные символы, используйте вместо этого:
источник
[[
?[[
здесь ничего не упрощается[[ "${file#./a_}" > 000749 ]]
, даже не сокращается. Мне не нравится использовать ненужный синтаксис, и он будет работать даже в таких простых оболочках, какdash
.[[
лучше справляется с пробелами и странностями (меня это тоже не волнует>
).[
хорошо, если вы процитируете переменную, как у меня, работает на гораздо больше оболочек и проще.Вы могли бы сделать что-то вроде этого:
Или:
Первый метод предполагает фиксированный префикс, удаляет его и проверяет значение.
Второй метод предполагает использование суффикса фиксированной длины (и общего фиксированного префикса) и опирается на этот факт; и что, хотя и
201
идет раньше31
в лексикографическом смысле, это не раньше031
.Проверьте это с помощью
echo
команды, и как только вы убедитесь, что она перечисляет правильные файлы, используйтеrm
вместо этого.источник
Оболочка POSIX
Первое решение terdon основано на расширении скобок, которое является свойством
bash
иksh
, однако, его нельзя использовать в стандартной/bin/sh
оболочке, на которую в Ubuntu есть символическая ссылка/bin/dash
.В тех случаях, когда вам приходится полагаться
/bin/sh
на переносимость ваших сценариев, обычно есть два подхода к этому. Можно было бы с помощью болтовни. Простоcd folderA
и оттуда бегиrm a_*
. Другой способ - реализовать C-стиль для альтернативы цикла с использованиемwhile <CONDITION>;do ...done
языка оболочки и отформатировать числа с помощьюprintf
:Обратите внимание, что здесь я использую
echo
. Заменитеecho "$filename"
наrm ./"$filename"
илиrm -- "$filename"
когда вы будете готовы удалить файлы. Также обратите внимание, что это должно быть выполнено, когда вы ужеcd
зашли в нужный каталог.(ab) используя awk
Awk, являющийся хорошим C-подобным языком, может помочь нам двумя способами: (1) мы можем сгенерировать имена файлов с помощью for-loop и отформатировать их с помощью
sprintf
функции, и (2) удалить указанные файлы с помощьюsystem()
команды, которая передаст наше сгенерированное имя файла иrm
команду к/bin/sh
:Perl
Продолжая идею переносимого подхода, где мы «генерируем» имена файлов, мы можем сделать то же самое в Perl:
источник
Так просто как
В вашем примере это
источник
a_00075
...