Как мне удалить файлы, кроме некоторых определенных файлов, переданных в качестве параметров?

В оболочке, поддерживающей <() (bash, ksh, zsh), вы можете преобразовать

$ cmd1 | cmd2 

в

$ cmd2 < <(cmd1)

Эти две формы должны быть эквивалентны с точки зрения конвейеризации. (Однако, я думаю, есть некоторые незначительные различия в том, как эти две формы обрабатывают такие вещи, как группа процессов и сигналы).

Для лучшего редактирования командной строки я рекомендую вам изучить возможности вашей оболочки для этого. Например, в bash есть set -o vi, который позволяет вам использовать vi-подобные ярлыки или переключаться в vim напрямую для более эффективного редактирования команды. По умолчанию set -o emacs использует ярлыки emacs (чтобы узнать о них больше, найдите в man bash readline (/readline)).

2
29.04.2019, 08:57
2 ответа

Попробуйте это (встроенные комментарии):

#!/bin/bash                                                                     
set -f     # Prevent e.g. *.txt from being expanded here

dir=$1     # Get the target directory and
shift      # remove from list of args

cmd="find $dir -type f"
while (( "$#" ))              # While there are more arguments left
do
    cmd="$cmd -not -name $1"  # add to not match
    shift                     # and remove from list of arguments
done
cmd="$cmd -exec rm -i {} ;"   # finally execute rm on the remaining matches

echo $cmd  # Print the final find command
$cmd       # And execute it

Я добавил -iк rm, чтобы он спрашивал перед удалением каждого файла. Но это можно, конечно, подкорректировать.

3
27.01.2020, 22:02
  1. Тот же механизм, что иlaenkeio , ответ , но более минималистичный. нет -переменная POSIX функция оболочки:

    rmexcept(){ find "$1" $(shift; printf " -not -name %s" ${@}) -exec rm '{}' \; ;}
    

    Команда оболочки printfвыполняет основную работу вместо forили whileпетля.

  2. Используя оболочку bash, shiftможно заменить параметром расширение:

    rmexcept(){ find "$1" $(printf " -not -name %s" ${@:2}) -exec rm '{}' \; ;}
    

Обратите внимание, что ни одна из функций не завершит задание, если результирующие команды findили rmдлиннее числа, возвращаемого getconf ARG_MAX. См.:Командная строка Bash и ограничение ввода .

0
27.01.2020, 22:02

Теги

Похожие вопросы