Регулярное выражение с положительным и отрицательным выбором в цикле for для перебора списка файлов - PullRequest
1 голос
/ 16 июня 2019

Мне неловко изо всех сил пытаться перебрать несколько файлов, выбранных один на основе нескольких критериев (определяемых регулярным выражением). Например, из файлов, перечисленных ниже, я бы хотел выбрать только файлы с расширением txt, кроме тех, которые содержат строку «cat»:

mousecatdog.txt
dogcowfox.gif
dogmousecat.txt
dogmousepig.txt

Так что я бы хотел получить только dogmousepig.txt из этого списка.

Я пытался использовать негативные взгляды, но получаю ошибку:

syntax error near unexpected token `('

Конечно, посмотрел другие темы на форуме и попытался решить проблему, добавив скобки () или включив shopt -s extglob, но безрезультатно.

Я использую Mac, а скрипт на bash.

 #!/bin/bash
    for FILE in ^((?!cat).)*.txt
     do
      printf "\$FILE\n" 
     done 

Ответы [ 2 ]

2 голосов
/ 16 июня 2019

Вы не можете использовать регулярные выражения после in, но вы можете использовать шаблоны глобуса. С shopt -s extglob вы можете использовать расширенные шаблоны:

#! /bin/bash
shopt -s extglob
for f in !(*cat*).txt ; do
    printf "$f\n"
done

Чтобы предотвратить расширение шаблона до самого себя, когда нет подходящих файлов, необходимо также включить nullglob.

1 голос
/ 17 июня 2019

Bash использует подстановочные знаки, а не регулярные выражения в вашем примере.

Я вижу два довольно простых решения:

1 - используйте подстановочный знак для положительного выбора и RE для отрицательного выбора, как сказал @Wiktor Stribizew в своем комментарии:

for FILE in *.txt; do
   if [[ ! $FILE =~ cat ]]; then
      printf "$FILE\n" 
   fi
done

2 - извлеките выходные данные расширения по шаблону (хотя это не будет работать правильно, если в именах файлов есть пробелы):

for FILE in `\ls -1 *.txt | grep -v cat`; do
   printf "$FILE\n"
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...