У меня есть ряд файлов, которые названы в соответствии с field.%d.vtk
и генерируются, когда я запускаю код C++. Коды выполняют ряд вычислений внутри цикла for и выводят вывод всякий раз, i%N == 0
когда где i
— переменная цикла, а N
— константа. По ошибке я установил N = 1
и теперь у меня огромное количество данных, которые мне не нужны. Я также не хочу перезапускать код.
Как написать скрипт bash, чтобы сохранить только все N
файлы, удалить остальные и переименовать оставшиеся файлы так, чтобы номера в них field.%d.vtk
были смежными? Извините, если это тривиально, но у меня очень ограниченный опыт в написании скриптов bash.
РЕДАКТИРОВАТЬ: Когда N=1
(по ошибке) диапазон %d
окажется в пределах [0, 1, ..., O(100 000)] (действительно большой), подходящим N
будет что-то около N=100
того, что сократит количество файлов до O(1000) или около того.
Спасибо
решение1
Если N=100, то их довольно легко вырезать. Следующий код удалит все файлы, которые не заканчиваются на 00.vtk
find -name '*.vtk' -not -name '*00.vtk' -exec rm {} +
Таким образом, останется 100.vtk, 200.vtk и т.д.
Затем, чтобы сделать их смежными, можно просто убрать 00:
rename 00.vtk .vtk *.vtk
Это предполагает стандартное переименование posix. Если у вас установлен perl rename, то это:
rename 's/00.vtk/.vtk/' *.vtk
решение2
for i in *.vtk
do
[[ $i =~ \.([0-9]*)\. ]] && ((BASH_REMATCH[1] % 100 != 0)) && echo $i
done
Измените echo
на rm
, когда дважды проверите эту команду!
решение3
Версия ответа Пола, предназначенная только для Bash( 4+) (то есть, она оставит только каждый 100-й файл .vtk, заканчивающийся на 00.vtk
, и переименует их, удалив 00
):
shopt -s extglob
rm ./!(*00).vtk
for f in ./*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done
Если вам нужна рекурсивность:
shopt -s extglob globstar
rm ./**/!(*00).vtk
for f in ./**/*.vtk; do mv "$f" "${f%00.vtk}.vtk"; done