Список файлов, которые соответствуют шаблону, но игнорируют файлы, которые соответствуют другому шаблону?

12

Допустим, у меня есть каталог с файлами a1, a2, a3, b1, b2, b3. Я хочу только сопоставлять файлы, которые начинаются с, aно не содержат 3. Я пытался, ls -I "*3" *a*но это возвращается a1 a2 a3, хотя я не хочу, чтобы это соответствовало a3. Это возможно с ls?

Стивен
источник
интересный разнообразный набор ответов здесь, но объяснение того, почему ls -I '* 3' a * терпит неудачу, было бы назидательно. и / или почему глобальный список оболочки впоследствии не фильтруется переключателем игнорирования на ls?
Феофраст
Страница man говорит об опции -I: do not list implied entries matching shell PATTERNоднако она не объясняет, что подразумевается под подразумеваемым , но я предполагаю, что она применима только к файлам, lsполучаемым с помощью глобальных расширений - и lsне раскрывает a*, оболочка делает это ,
Мюррей Дженсен

Ответы:

14

Только:

shopt -s extglob  
ls a!(*3*)
  • shopt -s extglob активирует расширенное сглаживание.
  • a соответствует старту a
  • !()отменяет матч внутри ()...
    • *3*который есть 3и что-нибудь до или после него.

$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls a!(*3*)
a1  a2  a2a  aa1  aa2
хаос
источник
1
К вашему сведению, требуетсяset -s extglob
Брайан
@ Брайан Да, только что заметил ^^
хаос
8

В существующих ответах хорошо изложен лучший способ сделать это с помощью шариков; Я включу это, потому что в большинстве случаев findэто лучший вариант, если вы хотите выполнить сценарии или дальнейшую обработку:

$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2

Вы можете передать ответ xargsдля простых действий или while readцикл для более сложных вещей.

Том Хант
источник
4

Простой способ

  • перечислить все файлы, которые соответствуют a*
  • затем удалите все строки, содержащие 3

Команда UNIX

ls -1 a* | grep -v 3

ls -1 показывает один файл в строке.

grepобычно находит строки, которые соответствуют шаблону, но при -vэтом поведение инвертируется, то есть grep находит строки, которые не соответствуют этому шаблону.

Питер К
источник
2
Привет Питер! Было бы лучше объяснить как можно подробнее, как работает ваше решение.
Даг
2
Разбор lsне является идеей goob: mywiki.wooledge.org/ParsingLs
хаос
3

С zshпомощью ~ оператора glob :

setopt extendedglob
print -rl -- a*~*3*

При этом gnu lsвы можете использовать два --ignoreварианта:

ls -I '[^a]*' -I '*3*'

первый игнорирует все имена файлов, которые не начинаются с, aа второй игнорирует имена файлов, которые содержат3

don_crissti
источник