Почему "*" работает по-разному в разных командах?

Это exодин -вкладыш.(exявляется предшественником и скриптовой формой vi.)

printf '%s\n' '$?pattern2?/pattern1/d' x | ex file.txt

Сохранение xи выход. Измените его на %p, если вы хотите просто распечатать измененный файл, но не сохранить изменения (хорошо для тестирования ).

$означает последнюю строку файла; ?pattern2?— адрес, означающий первый результат поиска pattern2в обратном направлении, начиная с текущей позиции; /pattern1/— адрес прямого -поиска, а d— команда удаления строки.

Используйте ex, когда вам нужна прямая и обратная адресация.


То же самое можно сделать интерактивно в viили Vim:

vim file.txt

Затем введите

:$?pattern2?/pattern1/d

и нажмите Enter.

Затем сохраните и выйдите, нажав :xEnter.

0
01.10.2019, 08:01
1 ответ

Когда такой шаблон, как abc*, используется в оболочке без кавычек, оболочка попытается сопоставить его с доступными именами файлов (это называется «генерация имени файла», но часто упоминается как «подстановка» ). Если он не соответствует какому-либо имени файла, большинствоsh-подобных оболочек оставят шаблон нераскрытым и передают его утилите как есть.

Пример:

$ touch xyz
$ touch abc*
$ tree
.
|-- abc*
`-- xyz

0 directory, 2 files
$ touch xyz*
$ tree
.
|-- abc*
`-- xyz

0 directory, 2 files

Команда touch xyz*не не создала файл с именем xyz*, поскольку имя файла xyzсоответствовало шаблону. Поэтому утилита touchбыла вызвана с именем файла xyz.

В оболочке bashустановка параметра оболочки failglobс shopt -s failglobзаставит оболочку жаловаться, если глобус оболочки ничему не соответствует:

$ shopt -s failglob
$ touch 123*
bash: no match: 123*

Эквивалентная опция включена по умолчанию в оболочке zsh.

Установка параметра оболочки nullglobвbash(или NULL_GLOBвzsh)приведет к исчезновению шаблона, если он не соответствует имени файла:

$ shopt -s nullglob
$ touch fo*
usage: touch [-acm] [-d ccyy-mm-ddTHH:MM:SS[.frac][Z]] [-r file]
             [-t [[cc]yy]mmddHHMM[.SS]] file...

(мы получаем ошибку от touch, так как она была вызвана без каких-либо аргументов)

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

$ touch "file*"
$ touch "file**"
$ touch "file***"
$ tree
.
|-- file*
|-- file**
`-- file***

0 directory, 3 files

Отсутствие кавычек в этом примере дало бы вам только один файл с именем file*(, если каталог изначально был пустым ), поскольку шаблоны file**и file***соответствуют этому первому имени file*.

7
28.01.2020, 02:14

Теги

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