
Когда я пытаюсь сопоставить все файлы с точкой в каталоге, .*
у меня возникает неприятный побочный эффект: помимо сопоставления всех (реальных) файлов и каталогов, он сопоставляет .
и ..
.
bash-3.2$ mv test/.* dest/
mv: rename test/. to dest/.: Invalid argument
mv: test/.. and dest/.. are identical
Это кажется действительно странным, поскольку они по сути являются «поддельными» каталогами, просто для того, чтобы упростить относительные пути. Они не являются частью содержимого каталога, и я не хочу, чтобы они сопоставлялись, когда я пытаюсь переместить содержимое одного каталога в другой. Я не могу придумать ни одного сценария, в котором я хотел бы, чтобы они сопоставлялись с .*
.
Так как же мне это отключить? (Помимо использования оболочки Z, которая не всегда доступна и которая может не быть оболочкой, используемой кем-то, запускающим написанную мной функцию.)
решение1
Вы можете использовать GLOBIGNORE
переменную bash.
GLOBIGNORE Список шаблонов, разделенных двоеточиями, определяющих набор имен файлов. игнорироваться при расширении имени пути. Если имя файла совпадает с Шаблон расширения имени пути также соответствует одному из шаблонов в GLOBIGNORE, он удаляется из списка совпадений.
и
.................-. Имена файлов ``.'' и ``..'' всегда игнорируется, если задано значение GLOBIGNORE и оно не равно нулю.
Итак, если вы установите
GLOBIGNORE='*/.:*/..'
то path/.*
не будет соответствовать .
и ..
, как вы просите.
решение2
Шаблон поиска будет выглядеть так .[^.]*
: он соответствует чему-то, содержащему не менее 2 символов, где второй символ не является точкой.
Документация по сопоставлению шаблонов имен файлов находится на странице руководства bash или здесь:http://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching
Джонатан Каллен поднимает хорошую тему. Вы можете использовать довольно простую расширенную модель
shopt -s extglob
ls -d .!(.|)