Если, по случайности, вы просто пытаетесь обработать кавычки для повторного использования оболочки, то вы можете сделать это, не удаляя их, и это тоже очень просто:
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'
Это вывод, из dash
которого обычно вывод с одинарными кавычками, как обычно '"'"'
. bash
сделал бы '\''
.
Замена выделенного, непустого, ненулевого байта другим одиночным байтом, вероятно, может быть выполнена быстрее всего в любой оболочке POSIX с помощью $IFS
и $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
ВЫХОД
"some ""crazy """"""""string ""here
Там я просто printf
так, чтобы вы могли видеть это, но, конечно, если бы я сделал:
var="$*"
... вместо printf
команды $var
значение «s будет то , что вы видите на выходе там.
Когда я set -f
даю команду оболочке не использовать глобус - в случае, если строка содержит символы, которые могут быть истолкованы как шаблоны глобуса. Я делаю это потому, что синтаксический анализатор оболочек расширяет шаблоны глобуса после того, как он выполняет разбиение поля на переменные. Globbing может быть снова включен, как set +f
. В целом - в сценариях - я считаю полезным установить мой взрыв следующим образом:
#!/usr/bin/sh -f
И затем, чтобы явно разрешить глобализацию с set +f
любой строкой, которую я мог бы хотеть.
Разделение полей происходит на основе символов в $IFS
.
Есть два вида $IFS
значений - $IFS
пробельные и $IFS
непробельные. $IFS
пробельных (пробел, табуляция, перевод строки) с разделителями полей указаны в Elide по последовательности к одному полю (или вообще ничего , если они не предшествуют что - то еще) - так ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Но все остальные указаны для оценки по одному полю для каждого вхождения - они не усекаются.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Все расширения переменных по умолчанию являются $IFS
массивами данных с разделителями - они разделяются на отдельные поля в соответствии с $IFS
. Когда вы "
цитируете единицу, вы переопределяете это свойство массива и оцениваете его как одну строку.
Поэтому, когда я делаю ...
IFS=\"\'\`; set -- $var
Я устанавливаю массив аргументов оболочки для множества $IFS
полей с разделителями, созданных $var
расширением. Когда он развернут, его составляющие значения для символов, содержащихся в нем $IFS
, теряются - теперь они являются только разделителями полей - так и есть \0NUL
.
"$*"
- как и другие переменные-расширения в двойных кавычках - также переопределяет свойства разделения поля $IFS
. Но, кроме того , он заменяет первый байт в $IFS
каждом поле с разделителями в "$@"
. Таким образом, потому что "
было первое значение во $IFS
всех последующих разделителей стать "
в "$*"
. И "
не нужно быть там, $IFS
когда ты его разделяешь. Вы можете изменить $IFS
после set -- $args
того, как другое значение целиком и его новый первый байт будет затем отображаться для полевых разделителей "$*"
. Более того, вы можете полностью удалить их следы, например:
set -- $var; IFS=; printf %s "$*"
ВЫХОД
some crazy string here
tr
. PE BASH хорош, но в этом случае tr намного быстрее. например,echo "$OUTPUT" | tr -dc '[[:alpha:]]'
поскольку вы хотите, чтобы были только буквенно-цифровые символы