Если на случайном этапе вы просто пытаетесь обработать кавычки для повторного использования оболочки, то вы можете сделать это , не удаляя их , и это также просто:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Эта оболочка функции цитирует любой массив arg, который вы передаете, и увеличивает его вывод на итерабельный аргумент.
Здесь это с несколькими аргументами:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
Этот выход из тире
, который, как правило, безопасно кавычки в одной кавычке, как '«'» '
. bash
будет выполнять '\"
.
В любой оболочке POSIX с $ IFS
и $ *
можно быстрее всего заменить набор байтов, отличных от пустых и пустых.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
"some ""crazy """"""""string ""here
Там я просто printf
это, чтобы вы могли видеть, но, конечно, если бы я сделал:
var="$*"
..., а не printf
команда $ var
значение будет то, что вы видите на выходе там.
Когда я задаю -f
, я инструктирую оболочку не на glob - в случае, если последовательность содержит символы, которые можно истолковать как glob узоров. Я делаю это, потому что синтаксический анализатор оболочек расширяет паттерны глоба после он выполняет разделение поля на переменные. глоббинг может быть повторно включен, как набор + f
. В общем - в сценариях - я считаю полезным задать свой удар, как:
#!/usr/bin/sh -f
И затем явно включить глоббинг с установить + f
на любой строке, которую я мог бы захотеть.
Разделение полей выполняется на основе символов в $ IFS
.
Существует два вида значений $ IFS
- $ IFS
пробел и $ IFS
пробел. $ IFS
пробел (космос, табуляция, новая строка) разделенные поля определяются как разделяемые последовательностью на одно поле (или вообще отсутствуют, если они не предшествуют чему-либо другому) - так что...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Но все остальные указаны для вычисления одного поля в каждом случае - они не усечены.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Все расширения переменных по умолчанию представляют собой массивы данных с разделителями $ IFS
- они разделены на отдельные поля в соответствии с $ IFS
. Когда вы "
- цитируете одно из них, вы переопределяете это свойство массива и оцениваете его как один ряд.
Так что, когда я это делаю...
IFS=\"\'\`; set -- $var
Я настройкой массив аргументов оболочки к множеству полей $ IFS
, разделенных расширением $ var
. При расширении его составляющих значений для символов, содержащихся в $ IFS
, теряется - теперь они являются только разделителями полей - \0NUL
.
«$ *»
- как и другие переменные расширения с двойными кавычками - также переопределяет качества разделения поля $ IFS
. Но, в дополнение ,он заменяет первый байт в $ IFS
для каждого разделенного поля в «$ @»
. Так как «
было первым значением в $ IFS
все последующие разделители становятся »
в «$ *»
. И "
не обязательно находиться в $ IFS
при разделении. Можно полностью изменить $ IFS
после наборов -- $ args
на другое значение, и его новый первый байт появится для разделителей полей в «$ *»
. Более того, можно удалить все следы, как
set -- $var; IFS=; printf %s "$*"
some crazy string here
-121--24039- Команда find
имеет для этого переключатель. Он называется -exec
.
$ find . -name '*.dcm' -exec dcmdjpeg {} {} \;
Имена файлов будут заменены найти
в местах {}
. Так что в вышеперечисленном мы будем делать это для каждого имени файла.
dcmdjpeg file1.dcm file1.dcm
dcmdjpeg file2.dcm file2.dcm
...
Если в именах файлов имеются места, можно использовать следующий метод:
$ find . -name '*.dcm' -exec dcmdjpeg "{}" "{}" \;
Можно заменить команду dcmdjpeg
командой echo
и выполнить приведенное выше для просмотра имен файлов, которые будут выполнены.
Скажем, что у меня были эти данные образца.
$ tree
.
|-- 1
| |-- 1.dcm
| |-- 1\ space.dcm
| |-- 2.dcm
| `-- 3.dcm
|-- 1.dcm
|-- 2
| |-- 1.dcm
| |-- 1\ space.dcm
| |-- 2.dcm
| `-- 3.dcm
|-- 2.dcm
|-- 3
| |-- 1.dcm
| |-- 1\ space.dcm
| |-- 2.dcm
| `-- 3.dcm
`-- 3.dcm
И теперь, когда мы запускаем 2-й пример, который обрабатывает места в именах файлов:
$ find . -name '*.dcm' -exec echo "{}" "{}" \;
./2.dcm ./2.dcm
./1/2.dcm ./1/2.dcm
./1/3.dcm ./1/3.dcm
./1/1 space.dcm ./1/1 space.dcm
./1/1.dcm ./1/1.dcm
./3.dcm ./3.dcm
./1.dcm ./1.dcm
./2/2.dcm ./2/2.dcm
./2/3.dcm ./2/3.dcm
./2/1 space.dcm ./2/1 space.dcm
./2/1.dcm ./2/1.dcm
./3/2.dcm ./3/2.dcm
./3/3.dcm ./3/3.dcm
./3/1 space.dcm ./3/1 space.dcm
./3/1.dcm ./3/1.dcm
В приведенном выше вы можете увидеть, как имена файлов повторяются дважды на каждый найденный файл.
-121--139945- Предположим, что в текущем каталоге имеется файлов1
. Затем:
$ find . -maxdepth 0 -name "file1"
$ find . file1 -maxdepth 0 -name "file1"
file1
Теперь рассмотрим, что говорится в документации:
-maxdepth 0 означает только применение тестов и действий к аргументам командной строки.
В моем первом примере выше только каталог .
отображается в командной строке. С .
не имеет имени file1
, в выходных данных ничего не указано. В моем втором примере выше оба .
и file1
перечислены в командной строке, и, поскольку file1
соответствует -имя «file1»
, он был возвращен в выходных данных
Другими словами, -maxdepth 0
означает не поиск каталогов или подкаталогов. Вместо этого следует искать только соответствующий файл среди файлов, явно перечисленных в командной строке.
В примерах в командной строке были перечислены только каталоги, ни один из которых не был назван file1
. Следовательно, никаких выходных данных.
Как правило, в командной строке можно присвоить имена многим файлам и каталогам. Например, здесь мы попробуем команду find
с 11 файлами и каталогами в командной строке:
$ ls
d1 file1 file10 file2 file3 file4 file5 file6 file7 file8 file9
$ find d1 file1 file10 file2 file3 file4 file5 file6 file7 file8 file9 -maxdepth 0 -name "file1"
file1
Рассмотрим:
$ find . file1 -maxdepth 0 -iname file1
file1
$ find . file1 file1 -maxdepth 0 -iname file1
file1
file1
$ find . file1 file1 -maxdepth 1 -iname file1
./file1
file1
file1
Видимо, как указывает Рамеш, find
будет следовать по каждому пути, указанному в командной строке, и искать совпадения, даже если пути ведут к тому же файлу, как в . файл
или даже если пути являются точными дубликатами, как в file1 file1
.