Баш: избавиться от "." и '..', когда циклически перебираются файлы, начинающиеся с '.' в папке - PullRequest
2 голосов
/ 31 марта 2010

Я хочу перебрать файлы, начинающиеся с '.' в каталоге x (x может быть любым путем):

$ for file in x/.*
> do
>     echo -n $file" "
> done
x/. x/.. x/..a x/.b

Как лучше всего избавиться от х / б и х / б??

Ответы [ 9 ]

5 голосов
/ 31 марта 2010

с bash, вы можете использовать GLOBIGNORE

$ ls -1tra
..
.test1
.test
test
.

$ for i in .*; do echo $i;done
.
..
.test
.test1

$ GLOBIGNORE=".:.."
$ for i in .*; do echo $i;done
.test
.test1
3 голосов
/ 31 марта 2010

Используйте шаблон .{[^.]*,.?*}, что означает любое имя, начинающееся с ., за которым следует символ, который не является ., или имя, начинающееся с .., за которым следует символ.

Также вы должны написать "$file" в кавычках, чтобы имена с пробелами не разбивались на части.

1 голос
/ 31 марта 2010

Решение, в котором используется только глобализация, поэтому вам не нужно беспокоиться о подстановке команд и цитировании:

.!(.|)

Для этого необходимо установить параметр оболочки extglob:

shopt -s extglob

Это, вероятно, очевидно, но конструкция !() означает что-либо, кроме одного из перечисленных шаблонов (ограниченных |).

1 голос
/ 31 марта 2010

Как уже указывалось, ls -A исключает. и ... из списка, не уверен, насколько он стандартен.

Вы также можете использовать find :

find .  -mindepth 1 -maxdepth 1 -name '.*'
0 голосов
/ 13 апреля 2016

Другой вариант - сохранить простоту глобализации и явно удалить ненужные пути:

for file in x/.* ; do
    [[ $file == */. || $file == */.. ]] && continue
    echo -n "$file "
done
0 голосов
/ 31 марта 2010

для файла в x / .][^.],.?менно*

Это будет соответствовать, например, .а .zoo.17 ... ..0 ..hello

но не будет совпадать , .. файлы-не-пуско-с-точкой

сломать его ...

{a, b} выполняет чередование, сначала сопоставляя a, затем сопоставляя b. Таким образом, мы могли бы также написать выше:

для файла в x /.[^.]* x /..?*

Итак, давайте рассмотрим первое:. [^.] * [^.] - это перевернутый класс символов - без карата ^ он будет соответствовать только точке; ^ инвертирует его так, что он будет соответствовать любому символу, кроме точки. После этого появляется звезда, которая будет соответствовать 0 или более символам любого вида. Таким образом, этот шаблон. [^.] * Будет сопоставлять файлы с именами, которые - начать с. - длиной не менее двух символов - второго персонажа нет. Из приведенных выше примеров это соответствует: .а .zoo.17

Теперь давайте рассмотрим второе: ..? * ? соответствует любому символу (но не 0 символов). Мы знакомы со звездой. Так что этот шаблон ..? * Будет сопоставлять файлы с именами, которые - начать с .. - длиной не менее трех символов Из приведенных выше примеров это соответствует: ... ..0 ..hello

Из-за способа чередования все файлы в первой группе будут сопоставляться первыми - они не будут сопоставляться с файлами во второй группе.

0 голосов
/ 31 марта 2010

(1) Используйте 2 шаблона: $ echo x /.??* x /.[^.] - есть другие комбинации. Если вы используете другой, убедитесь, что он поймает "..." и ".a"

(2) Используйте GLOBIGNORE и исключите 2 записи: $ GLOBIGNORE = '* /.: * / ..'; echo x /.*

(3) Используйте dotglob с GLOBIGNORE. Это будет автоматически исключено. и .., но теперь вы должны исключить "все остальное" $ shopt -s dotglob; GLOBIGNORE = '* / [. ^] *'; эхо х / *

0 голосов
/ 31 марта 2010

Используйте ls -A в Mac OS X. Проверьте страницу руководства для вашей реализации для локальных опций. Эта команда

ls -A | grep '^\.'

Дали мне список, который вы ищете.

0 голосов
/ 31 марта 2010
for file in x/.*; do echo  "$file "; done | grep -v "x/\.\{1,2\} $" | tr -d '\n'

Пробел после $file и до $ в grep важен. Это гарантирует, что у вас есть пробелы между списками и что не все свернуто.

или более обобщенно

for file in somedir/.*; do echo  "$file "; done | grep -v "\w/\.\{1,2\} $" | tr -d '\n'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...