Подстановочные знаки раскрываются оболочкой, а не командой. find
— одна из немногих команд, выполняющих сопоставление с подстановочными знаками, аналогичное оболочке, в свое время.
Когда вы запускаете ls *.xml
, сначала оболочка расширяет *.xml
до списка соответствующих файлов, например. file1.xml
file2.xml
file3.xml
, а затем оболочка вызывает ls
с результирующим списком аргументов file1.xml
file2.xml
file3.xml
. Вот почему вы видите тот же список имен файлов с echo *.xml
, хотя echo
ничего не знает о файлах и не заботится о том, являются ли его аргументы именами файлов.
Когда вы бежитеfind. -name "*.xml"
:
find
, .
, -name
, *.xml
, где *
цитируется. Поскольку *
взят в кавычки, это обычный символ с точки зрения оболочки. find
с указанным списком аргументов :.
, -name
, *.xml
. find
ищет файлы, имя которых соответствует шаблону *.xml
в любом каталоге в текущем каталоге. При запуске find. -name *.xml
и отсутствии файлов, соответствующих*.xml
:
find
, .
, -name
, *.xml
, где *
не заключено в кавычки. *.xml
содержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла. Поскольку соответствующих имен файлов нет, шаблон остается нераскрытым. find
с полученным списком аргументов: .
, -name
, *.xml
. find
ищет файлы, имя которых соответствует шаблону *.xml
в любом каталоге в текущем каталоге.Когда вы запускаете find. -name *.xml
и текущий каталог содержит file1.xml
, file2.xml
иfile3.xml
:
find
, .
, -name
, *.xml
, где *
не заключено в кавычки. *.xml
содержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла.:*.xml
заменяется списком совпадающих имен файлов. find
с полученным списком аргументов: .
, -name
, file1.xml
, file2.xml
, file3.xml
. find
жалуется на синтаксическую ошибку, когда достигает file2.xml
. Когда вы запускаете find. -name *.xml
и текущий каталог содержит один соответствующий файлfile.xml
:
find
, .
, -name
, *.xml
, где *
не заключено в кавычки. *.xml
содержит подстановочный знак без кавычек, оболочка выполняет генерацию имени файла :*.xml
, заменяется списком совпадающих имен файлов. find
с полученным списком аргументов: .
, -name
, file.xml
. find
видит вполне допустимую команду, но, вероятно, это не то, что вы хотели.:find
сказано искать файлы с именем file.xml
в любом каталоге, а не искать какой-либо файл, соответствующий *.xml
. (Оценка и расширение оболочки имеет множество других функций. Я упомянул только те, которые актуальны здесь.)
(То, что я описываю, является поведением по умолчанию большинства распространенных оболочек :sh, bash, dash, ksh, … Некоторые оболочки могут быть настроены для отображения ошибки вместо запуска команды с нерасширенными подстановочными знаками,или расширить не соответствующие -подстановочные знаки до пустого списка. Ни один из них не поможет здесь.)
$ sed '/^\$/{s/^/start /; s/$/ end/;}' abc.txt
start $ hello end
start $ yes end
r no change
другой sed
подход:
sed '/^\$/ s/.*/start & end/' infile
в sed
, &
— это обратная -ссылка на согласованную часть шаблона в s/<pattern>/<replace>/
.
с помощью awk
вы также можете сделать то же самое:
awk '/^\$/{ $0="start " $0 " end" }1' infile
в awk
, $0
представляет текущую запись/строку; записи/строки разделены на основе встроенной в awk переменной -вRS
(R запись S разделитель ), по умолчанию \n
ewline; давайте посмотрим некоторые встроенные -значения переменных по умолчанию, которые они устанавливают, когда awk читает запись:
awk -d- '0' <<<'1'
awk состоит из двух частей, condition { action }
по крайней мере одна из которых должна присутствовать в команде awk.
наше условие здесь — это шаблон и это/^\$/
(начало ^
с долларом \$
, мы избежали этого, потому что как ^
является якорем для начала записи, $
является привязкой к концу этой записи ).
в $0="start " $0 " end"
мы обновляем запись, добавляя к ней фиксированные строки start
и end
и записываем обратно в $0
.
/pattern/ { action }1
, здесь 1
на самом деле является всегда истинным условием, которое включает действие печати aek по умолчанию; вместо этого вы можете написать любое условие, которое приводит к истинности и запускает действие печати.
awk '/pattern/ { action }; 1!=0'
awk '/pattern/ { action }3'
...
или используйте само действие print
:
awk '/pattern/ { action }; { print }'