Как перечислить все файлы в каталоге, исключив по шаблону.
Например: все *.pdf исключаем *_book.pdf. Я пробую так:
for $PDF in $(ls *.pdf | grep -v *_book.pdf);
do
echo "File $PDF"
done
Это хороший способ? Есть ли другие способы? Использованныйеслизаявление или другое.
решение1
Также переменная, которую вы объявляете в 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
.