Как я могу использовать обратные или отрицательные подстановочные знаки, когда сопоставление с образцом в unix/linux окружает?

317
задан 7 revs, 3 users 100% 19 October 2011 в 06:24
поделиться

6 ответов

В Bash можно сделать это путем включения extglob опция, как это (замена ls с cp и добавить целевой каталог, конечно)

~/foobar> shopt extglob
extglob        off
~/foobar> ls
abar  afoo  bbar  bfoo
~/foobar> ls !(b*)
-bash: !: event not found
~/foobar> shopt -s extglob  # Enables extglob
~/foobar> ls !(b*)
abar  afoo
~/foobar> ls !(a*)
bbar  bfoo
~/foobar> ls !(*foo)
abar  bbar

, можно позже отключить extglob с

shopt -u extglob
361
ответ дан bain 23 November 2019 в 01:02
поделиться

extglob опция оболочки дает Вам более мощное сопоставление с образцом в командной строке.

Вы включаете его с shopt -s extglob и выключаете его с shopt -u extglob.

В Вашем примере, Вы первоначально сделали бы:

$ shopt -s extglob
$ cp !(*Music*) /target_directory

полное доступное расширение закончилось шарик , операторы резкого звука (выборка от man bash):

, Если опция оболочки extglob включена с помощью shopt встроенного, несколько расширенных операторов сопоставления с образцом распознаны. В следующем описании стандартный список крачки является списком одного или нескольких шаблонов, разделенных |. Составные шаблоны могут быть сформированы с помощью одного или нескольких следующих подшаблонов:

  • ? (список шаблона)
    нуль Соответствий или одно возникновение данных шаблонов
  • * (список шаблона)
    нуль Соответствий или больше случаев данных шаблонов
  • + (список шаблона)
    Соответствия одни или несколько случаев данных шаблонов
  • (список шаблона)
    Соответствия один из данных шаблонов
  • ! (список шаблона)
    Соответствия что-либо кроме одного из данных шаблонов

Так, например, если Вы хотели перечислить все файлы в текущем каталоге, которые не являются .c или .h файлы, Вы сделали бы:

$ ls -d !(*@(.c|.h))

, Конечно, нормальная оболочка globing работы, таким образом, последний пример мог также быть записан как:

$ ls -d !(*.[ch])
222
ответ дан Freedo 23 November 2019 в 01:02
поделиться

Не в ударе (что я знаю о), но:

cp `ls | grep -v Music` /target_directory

я знаю, что это не точно, что Вы искали, но это решит Ваш пример.

23
ответ дан ejgottl 23 November 2019 в 01:02
поделиться

Если Вы хотите избежать стоимости мадам использования исполнительной команды, я полагаю, что можно добиться большего успеха с xargs. Я думаю, что следующее является более эффективной альтернативой

find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec



find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/
7
ответ дан Steve 23 November 2019 в 01:02
поделиться

Можно также использовать довольно простое for цикл:

for f in `find . -not -name "*Music*"`
do
    cp $f /target/dir
done
5
ответ дан mipadi 23 November 2019 в 01:02
поделиться

Одно решение для этого может быть найдено с находкой.

$ mkdir foo bar
$ touch foo/a.txt foo/Music.txt
$ find foo -type f ! -name '*Music*' -exec cp {} bar \;
$ ls bar
a.txt

Находят, имеет довольно много опций, можно стать довольно конкретными по поводу того, что Вы включаете и исключаете.

Редактирование: Adam в комментариях отметил, что это рекурсивно. найдите опции mindepth, и maxdepth может быть полезным в управлении этим.

3
ответ дан Daniel Bungert 23 November 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: