1

У меня есть ряд файлов, которые названы в соответствии с 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) или около того.

Спасибо

3 ответа3

3

Если 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
0

Bash(4+)- только версия ответа Павла (поэтому он будет оставлять только каждый сотый файл .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
0
for i in *.vtk
do
    [[ $i =~ \.([0-9]*)\. ]] && ((BASH_REMATCH[1] % 100 != 0)) && echo $i
done

Измените echo на rm когда вы дважды проверили эту команду!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .