Я имею folderA
это имеет некоторые файлы с последовательностью числа, запускающейся с a_000000
. То, что я хочу сделать, должно удалить файлы, начинающие с определенного числа: скажем, a_000750
до конца файлов в этом folderA
. Кто-либо мог советовать, как сделать этот сценарий оболочки использования?
Принятие Вас знает или может предположить конец диапазона, Вы могли использовать расширения фигурной скобки :
rm a_{000750..000850}
Вышеупомянутое будет удалять этот 101 файл между a_000750 и a_000850 включительно (и жаловаться на имена файлов, которые относятся к несуществующим файлам). Если у Вас есть слишком много файлов для этого, используйте find
:
find . -name 'a_*' | while read file; do
[ "${file#./a_}" -gt 000749 ] && rm -v "$file"
done
Здесь, find
просто списки все файлы, соответствующие a_*
. Список передается while
цикл, где каждое имя файла читается в переменную $file
. Затем с помощью удара обработка строк функции, если числовая часть (находят файлы печати как ./file
, таким образом ${file#./a_}
печать только число) 000750
или больше, файл удален. Эти -v
просто там, таким образом, Вы видите, какие файлы были удалены.
Примечание, что вышеупомянутое принимает нормальные имена файлов. Если Ваши имена могут иметь пробелы, новые строки или другие странные символы, используйте это вместо этого:
find . -name 'a_*' -print0 | while IFS= read -rd '' file; do
[ "${file#./a_}" -gt 000749 ] && rm -v "$file"
done
Вы могли сделать что-то вроде этого:
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
вместо этого.
Столь же простой как
rm partialfilename* -f
В Вашем примере это
rm a_00075* -f
первое решение terdon полагается на расширение фигурной скобки, которое является свойством bash
и ksh
, однако это не может использоваться в стандарте /bin/sh
оболочка, которая на Ubuntu является symlinked к /bin/dash
.
В случаях, где необходимо положиться /bin/sh
для мобильности Ваших сценариев обычно существует два способа приблизиться к этому. Можно было бы быть через globbing. Просто cd folderA
и оттуда выполненный rm a_*
. Другой путь, должен был бы реализовать C-стиль для использования альтернативы цикла 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) мы можем генерировать имена файлов с для цикла и отформатировать их через sprintf
функция, и (2) удаляет, сказал что файлы через system()
команда, которая передаст наше сгенерированное имя файла и rm
команда к /bin/sh
:
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)}'
В Bash вы можете запустить:
for i in {1001..3000} ; do rm file_"$i".dat ; done