Bash - для цикла исключить файлы с определенным шаблоном в имени файла прямо перед типом файла

Я пытаюсь запустить цикл for, но пытаюсь исключить файлы с определенным шаблоном в имени файла. Это команда, которую я использую:

for file in /home/ubuntu/discovery/download/*![.en].mp4; do

Я хотел бы, чтобы это имя файла было включено:

Blub - S03E10 - Nervous Breakdown.mp4

но это имя файла исключить

Blub - S03E10 - Nervous Breakdown.en.mp4

Не могу заставить его работать. Что я делаю не так?

заранее спасибо

Я бы посоветовал вам использовать find для создания списка нужных файлов (без исключений), а затем передать этот список в цикл while/read, например, while read -r fname; do do_some_stuff_with_fname; done < <(find /home/unbuntu/discovery/download ... exclude_some_file_types ...)

markp-fuso 30.03.2023 20:33

@markp-fuso Синтаксис questioni близок к правильному! Смотрите мой ответ!

F. Hauri - Give Up GitHub 30.03.2023 20:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
65
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Что я делаю не так?

В стандартной подстановке нет операторов группировки или группового отрицания (хотя в расширенной версии они есть). В вашем конкретном контексте я бы просто отфильтровал ненужные файлы внутри цикла:

for file in /home/ubuntu/discovery/download/*.mp4; do
  case $file in
    *.en.mp4) continue;;
  esac

  # ...
done

И это должно работать в любой оболочке семейства Bourne, а не только в Bash.

Расширение пути: «не совпадает», с включенным extglob:

         !(pattern-list)
                Matches anything except one of the given patterns

Попробуй это:

for file in /home/ubuntu/discovery/download/!(*.en).mp4; do
    ...

Если нет файлов, соответствующих шаблону глобуса, file будет установлен на шаблон глобуса. Либо убедитесь, что путь в file существует, либо включите nullglob с помощью shopt -s nullglob.

Sanford Freedman 30.03.2023 21:09

Правильно., но это то же самое поведение, что и /path/*! Вы можете проверить, используя [ -$àfile ]...

F. Hauri - Give Up GitHub 31.03.2023 07:37

Один вопрос: почему !(*.en).mp4 работает, а *!(.en).mp4 нет?

Philippe 31.03.2023 09:00

@Филипп, потому что узор должен начинаться с !. Ака !(...) правильно, *!( ...) — неизвестная модель. См. Удаление всех файлов, кроме некоторых, из каталога

F. Hauri - Give Up GitHub 07.04.2023 09:36

Другой подход заключается в переборе всех файлов, пропуская те, которые имеют нежелательные шаблоны имен. Просто не забудьте также обработать случай, когда файлы не найдены, потому что в этом случае file устанавливается равным шаблону глобуса. Часто вы можете справиться с этой ситуацией, убедившись, что путь в file действительно существует (-e "${file}").

for file in /home/ubuntu/discovery/download/*.mp4; do
    [[ -e "${file}" && "${file}" != *.en.mp4 ]] || continue
    echo ${file}
done
Ответ принят как подходящий

Другой альтернативой может быть:

shopt -s nullglob
for file in /home/ubuntu/discovery/download/*{[^n],[^e]n,[^.]en}.mp4
do
# ...
done

Другие вопросы по теме