Intereting Posts
Захватите среднюю нагрузку сверху Задержка systemd, если файл существует скрипт, в котором перечислены все файлы в каталоге и подкаталогах, отсортированных по размеру, перечисляя только имена файлов, а не полные пути Как установить clang 3.9 или выше с помощью apt-get на Linux Mint? binary может запускаться только при запуске после создания символической ссылки на него Веб-сайт активен, но доменное имя не отображается в поиске WhoIs из командной строки Linux Обратный обмен именами файлов в папке снизу вверх Подключен к VPN, но не удается подключить хосты в удаленной сети ps пользовательский выход в RHEL 6.2 Означает ли Windows символические ссылки Linux? Как предотвратить случайную выходную консоль от взлома терминала? Какие политики SELinux применяются к haproxy? Новое ядро ​​из Backports не загружается Отредактировано /etc/cron.d/anacron, изменения сразу же действуют? Как определить, заблокированы ли администраторы пакетов прокси-сервером

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

Предположим, что у меня есть каталог с тысячами файлов; как я могу открыть все файлы, чье имя содержит строки «красный» и «зеленый»?

(Исходя из предположения, что вы ищете имена файлов, которые содержат как строку «красный», так и строку «зеленый»)

Чтобы бесцельно использовать bash для проверки имен файлов против «красного» и «зеленого» с помощью оператора регулярного выражения =~ :

 for f in * do [[ $f =~ red && $f =~ green ]] && echo Bash: yes: "$f" || echo Bash: no: "$f" done 

Чтобы использовать стандартный синтаксис оболочки, используя case и globs, чтобы найти те же файлы:

 for f in * do case "$f" in *green*red*|*red*green*) echo Case: yes: $f;; *) echo Case: no: $f;; esac done 

Еще проще, с подбором вашей оболочки:

 printf "Glob: %s\n" *green*red* *red*green* 

Пример прогона:

 $ touch ab aredgreenb agreenredb agreenbred aredbgreen red green redgreen greenred $ for f in * > do > [[ $f =~ red && $f =~ green ]] && echo Bash: yes: "$f" || echo Bash: no: "$f" > done Bash: no: a Bash: yes: agreenbred Bash: yes: agreenredb Bash: yes: aredbgreen Bash: yes: aredgreenb Bash: no: b Bash: no: green Bash: yes: greenred Bash: no: red Bash: yes: redgreen $ for f in * > do > case "$f" in > *green*red*|*red*green*) echo Case: yes: $f;; > *) echo Case: no: $f;; > esac > done Case: no: a Case: yes: agreenbred Case: yes: agreenredb Case: yes: aredbgreen Case: yes: aredgreenb Case: no: b Case: no: green Case: yes: greenred Case: no: red Case: yes: redgreen $ printf "Glob: %s\n" *green*red* *red*green* Glob: agreenbred Glob: agreenredb Glob: greenred Glob: aredbgreen Glob: aredgreenb Glob: redgreen 
 find . -type f -name '*red*' -name '*green*' -exec echo {} + 

Замените echo с помощью vi , gvim , less или любой другой команды, с которой вы хотите открыть файлы.

Обратите внимание: некоторые программы не могут обрабатывать несколько имен файлов в командной строке. Если выбранная вами программа является одной из них, замените + в конце строки на \; , Это будет запускать команду один раз для каждого имени файла, а не только один раз с длинным списком имен файлов.

xdg-open – одна из таких команд. Он обнаруживает, какой файл запрашивается для открытия, а затем для открытия файла используется либо системная программа по умолчанию (или ваша предпочтительная программа, если вы переопределили значение по умолчанию). Если он не распознает тип файла, он попросит вас открыть его.

Использование его с подобным find является полезным и одновременно раздражающим. Попробуйте, и вы поймете, почему (вы увидите много окон, открывающихся один за другим … по одному для каждого подходящего имени файла).

 find . -type f -name '*red*' -name '*green*' -exec xdg-open {} \; 

BTW, если вы хотите найти файлы, соответствующие *red* OR *green* , вам придется использовать круглые скобки, чтобы указать приоритет для операторов «и» ( -a ) и «или» ( -o ). BTW, когда вы запускаете find с несколькими предикатами, как указано выше, оператор по умолчанию является -a , т.е. предикаты логически AND-ed вместе.

Скобки также имеют особое значение для оболочки, поэтому должны быть экранированы с обратным слэшем, поэтому они передаются команде find, а не интерпретируются оболочкой.

 find . -type f \( -name '*red*' -o -name '*green*' \) -exec echo {} + 

Прочитайте это как «обычный файл AND (имя файла, соответствующее« * red * »OR '* green *')"

С zsh :

 setopt extendedglob # best in ~/.zshrc ls -ld -- *green*~^*red* 

Оператор ~ glob предназначен для исключения ( и не ). ^ для не . Так что комбинация есть, а не нет , так и . IOW, который соответствует файлам с green в своих именах, кроме тех, которые не содержат red .

Чтобы также включить скрытые файлы, добавьте квалификатор (D) glob.

Вы также можете использовать квалификаторы glob для сопоставления имен файлов с setopt rematchpcre , а с помощью setopt rematchpcre вы можете сделать эти setopt rematchpcre PCRE, где вы можете использовать операторы с setopt rematchpcre для достижения и :

 re() { setopt localoptions rematchpcre [[ $REPLY =~ $1 ]] } ls -ld -- *(e:'re "(?=.*green).*red"':) 

Или:

 re() { setopt localoptions rematchpcre [[ $REPLY =~ $RE ]] } RE='(?=.*green).*red'; ls -ld -- *(+re) 

С помощью ksh или bash -O extglob

 ls -ld -- !(!(*green*)|!(*red*)) 

Опять же, двойное отрицание: все, кроме файлов, которые либо не содержат green , либо не содержат red .

Вы также можете сделать

 ls -ld -- @(*green*red*|*red*green*) 

Но это не универсально для любой модели. Например, для файлов, содержащих abc и bcd , вам понадобится @(*abc*bcd*|*abcd*|*bcd*abc*) , для сопоставления файлов ??? и *x* , @(x??|?x?|??x)

С ksh93

ksh93 есть некоторые и операторы ksh93 :

 ls -ld -- @(*green*&*red*) 

Или используя его расширенные регулярные выражения (введенные с оператором glob ~(A:...) ):

 ls -ld -- ~(A:.*green.*&.*red.*) 

Вы также можете использовать perl-like операторы ksh93 в ksh93 :

 ls -ld -- ~(P:(?=.*green).*red.*) 

Простой, предполагая, что команда open может обрабатывать несколько аргументов:

 open *red* *green* 

Изменить: извините, я читал вопрос как открытие (файлы с красным именем) и (файлы с зеленым именем); виноват.

Следующее использует extglob и избегает двойного счета в случае файлов с именем redgreenred :

 $ shopt -s extglob # turn on extended globbing $ printf "extglob: %s\n" @(*green*red*|*red*green*) extglob: agreenbred extglob: agreenredb extglob: aredbgreen extglob: aredgreenb extglob: greenred extglob: redgreen extglob: redgreenred $ shopt -u extglob # turn off extended globbing