Перечислить файлы *.pdf исключить *_book.pdf

Перечислить файлы *.pdf исключить *_book.pdf

Как перечислить все файлы в каталоге, исключив по шаблону.

Например: все *.pdf исключаем *_book.pdf. Я пробую так:

for $PDF in $(ls *.pdf | grep -v *_book.pdf);
do
   echo "File $PDF"
done

Это хороший способ? Есть ли другие способы? Использованныйеслизаявление или другое.

решение1

Не используйте lsв скриптах.

Также переменная, которую вы объявляете в forцикле, не должна иметь знака доллара. Знак доллараинтерполируетзначение переменной; $PDFчитается как «текущее значение переменной, имя которой PDF«.

for PDF in *.pdf
do
    case $PDF in
     *_book.pdf) continue;;
    esac
    echo "File $PDF"
done

Синтаксис caseпугает некоторых новичков, но я предпочитаю его ifдля таких вещей. Но если вы предпочитаете, вы можете использовать

    if [[ $PDF =~ _book\.pdf$ ]]; then
        continue
    fi

или стенография

    [[ $PDF =~ _book\.pdf$ ]] && continue

caseимеет дополнительное преимущество в том, что он переносим на POSIX shи даже на старый добрый оригинальный Bourne sh.

Обратите внимание, что шаблон в caseпредставляет собой глоб, тогда как [[ $variable =~ regex ]]в нем используется регулярное выражение (поэтому не должно быть *before _book).

решение2

Используя shopt -s extglob(который может быть значением по умолчанию в вашей системе, в противном случае установите его), вы можете использовать расширенное соответствие, включая шаблоны отрицательного соответствия:

# Directry contents
>ls -1
1_book_not.pdf
1_book.pdf
1.pdf
1.txt

# With negative match
>ls -1 !(*_book).pdf
1_book_not.pdf
1.pdf

решение3

У вас была небольшая синтаксическая ошибка в forвыражении. Попробуйте следующее:

for PDF in $(ls *.pdf | grep -v *_book.pdf);
do
   echo "File $PDF"
done

Кажется, это работает хорошо.

решение4

Другой вариант — использовать find:

find . -maxdepth 1 -name '*.pdf' ! -name '*_book.pdf'

Например, рассмотрим каталог с этими четырьмя файлами:

$ ls
a_book.pdf  book.txt  nook.pdf  not_book1.pdf

Теперь выполните нашу команду:

$ find . -maxdepth 1 -name '*.pdf' ! -name '*_book.pdf'
./not_book1.pdf
./nook.pdf

Как это работает

  • find .сообщает find о необходимости начать поиск в текущем каталоге.

  • -maxdepth 1сообщает find о необходимости пропускать подкаталоги.

  • -name '*.pdf'указывает find искать файлы, имена которых заканчиваются на .pdf.

  • ! -name '*_book.pdf'сообщает finds о необходимости исключить из вывода любой файл, имя которого заканчивается на _book.pdf.

Связанный контент