Удаление определенных файлов на основе имени файла из терминала

13

У меня есть каталог, содержащий файлы с именами

rho_0.txt
rho_5000.txt
rho_10000.txt
rho_150000.txt
rho_200000.txt

и так далее. Я хотел бы удалить все те, которые кратны 5000.

Я попробовал следующее:, printf 'rho_%d.txt\n' $(seq 5000 10000 25000) | rmно это дало мне ответ rm: missing operand.

Есть ли другой способ сделать это?

BillyJean
источник
6
Независимо от того, как вы это делаете, я рекомендую (для безопасности) переместить нужные файлы в каталог, а затем, когда вы подтвердите, что все и только файлы, которые должны быть удалены, находятся в каталоге, удалите каталог.
user117529
Безопасность важна здесь. Я обычно проверяю эти вещи lsсначала.
шотландец

Ответы:

49

Вам не нужен цикл или дополнительные команды, где у вас есть Bash Shell Brace Expansion.

rm -f rho_{0..200000..5000}.txt

Объяснение : {start..end..step}. -fИгнорировать приглашение на несуществующие файлы.


Ps Чтобы сохранить безопасность и проверить, какие файлы будут удалены, сначала выполните тест с:

ls -1 rho_{0..200000..5000}.txt
αғsнιη
источник
13

rmне читает со стандартного ввода. Вы могли бы сделать:

for i in $(seq 5000 5000 25000); do
    rm -i rho_${i}.txt
done

Я включаю -iопцию, чтобы rmзапросить перед удалением, чтобы вы могли проверить поведение. Если вы уверены, что делаете то, что хотите, вы можете опустить эту опцию.

Изменить: В качестве альтернативы, вы можете сделать:

for ((i = 5000; i <= 25000; i += 5000)); do
    rm -i rho_${i}.txt
done

Эта форма может быть более знакома, если вы занимались программированием.

Энди Далтон
источник
12

Вы не можете передать в программу, как если бы содержимое канала было аргументами. Это отправлено через стандартный ввод.

Вы должны использовать xarg для этой цели:

printf 'rho_%d.txt\n' $(seq 5000 10000 25000) | xargs rm 

но сначала вы можете попробовать с помощью echo проверить, все ли так, как вы намереваетесь:

printf 'rho_%d.txt\n' $(seq 5000 10000 25000) | xargs echo
M4rty
источник
Если в вашей версии seqесть опция -f/, --formatвы можете использовать ее вместо обходного пути printfи подстановки команд.
Дэвид Фёрстер
Спасибо, я только что ответил, используя команду, использованную в вопросе, и пытаясь объяснить его ошибку rm
M4rty
9

Кто-то исправит меня, если я ошибаюсь, но если все файлы, которые начинаются с, rho_имеют эту форму, разве это не эквивалентно

rm rho_0.txt rho_*[05]000.txt

Поскольку число (отличное от 0) кратно 5000 тогда и только тогда, когда оно заканчивается в 0000 или 5000.

(0 является особым случаем, поскольку он кратен 5000, но обычно записывается без дополнительных начальных нулей. Если вы не намеревались включать 0, выньте его из приведенной выше строки.)

Конечно, это следует использовать, только если все rho_*.txtфайлы в вашем каталоге имеют желаемую форму. Не используйте его, если ваш каталог также содержит rho_please_dont_delete_me_5000.txt.

(Замечание по математике: это работает именно потому, что все главные факторы 5000, а именно 2 и 5, также являются главными факторами базы, на которой мы работаем, 10. Эквивалентно, есть достаточно большая сила 10 (а именно 10000), которая равна делится на 5000. Нет аналогичного трюка для сопоставления всех тех, которые кратны 3000.)

Нейт Элдридж
источник
На самом деле это лучший ответ.
Цезарь