Есть много способов заменить символы в переменной.
Кратчайший путь, который я обнаружил, tr
это пока:
OUTPUT=a\'b\"c\`d_123and_a_lot_more
OUTPUT=$(echo "$OUTPUT"|tr -d "'\`\"")
echo $OUTPUT
Есть ли более быстрый способ? И это со ссылкой на безопасные цитаты , как '
, "
и `само по себе?
tr
. PE BASH хорош, но в этом случае tr намного быстрее. например,echo "$OUTPUT" | tr -dc '[[:alpha:]]'
поскольку вы хотите, чтобы были только буквенно-цифровые символыecho "$OUTPUT"
, Или лучше:printf "%s\n" "$OUTPUT"
. (Что происходит, когдаOUTPUT="-n"
?)Ответы:
Посмотрим. Самое короткое, что я могу придумать, это настройка вашего
tr
решения:Другие альтернативы включают уже упомянутое подстановку переменных, которая может быть короче, чем показано до сих пор:
И
sed
конечно, хотя это длиннее с точки зрения символов:Я не уверен, что вы имеете в виду самое короткое по продолжительности или по времени. С точки зрения длины, эти два настолько коротки, насколько это возможно (или как я могу получить это в любом случае), когда дело доходит до удаления этих конкретных символов. Итак, какой самый быстрый? Я проверил, установив
OUTPUT
переменную в то, что вы имели в своем примере, но повторил несколько десятков раз:Как вы можете видеть,
tr
очевидно, что он самый быстрый, за ним внимательно следятsed
. Кроме того, кажется, что использованиеecho
на самом деле немного быстрее, чем использование<<<
:Поскольку разница крошечная, я выполнил вышеуказанные тесты 10 раз для каждого из двух, и оказалось, что самый быстрый - это тот, с которого вам пришлось начинать:
Однако это меняется, если принять во внимание издержки, связанные с назначением переменной, здесь использование
tr
немного медленнее, чем простая замена:Итак, в заключение, когда вы просто хотите просмотреть результаты, используйте,
tr
но если вы хотите переназначить переменную, использование функций манипуляции со строками оболочки выполняется быстрее, поскольку они избегают накладных расходов при запуске отдельной подоболочки.источник
OUTPUT
, вы должны учитывать команды замещения подоболочку накладные расходы , связанныеtr
иsed
решенияOUTPUT="${OUTPUT//[`\"\']/}"
не подразумевает подстановку командВы можете использовать подстановку переменных :
Используйте этот синтаксис:
${parameter//pattern/string}
чтобы заменить все вхождения шаблона на строку.источник
echo ${OUTPUT//[`\"\']/x}
даетaxbxcxa
В bash или zsh это так:
Обратите внимание, что
${VAR//PATTERN/}
удаляет все экземпляры шаблона. Для получения дополнительной информации расширение параметров bashЭто решение должно быть самым быстрым для коротких строк, потому что оно не требует запуска каких-либо внешних программ. Однако для очень длинных строк верно обратное - лучше использовать специальный инструмент для текстовых операций, например:
источник
tr
быстрее. Регулярные выражения и глобусы дороги, и, хотя здесь нет внешней программы, bash всегда будет работать медленнее, чем что-то подобноеtr
.tr
выигрывает (см. Мой ответ). Я согласен, что это будет зависеть от многих факторов, но именно поэтому вы не можете сказать, какой из них выиграет, фактически не проверяя его.Если, по случайности, вы просто пытаетесь обработать кавычки для повторного использования оболочки, то вы можете сделать это, не удаляя их, и это тоже очень просто:
Эта функциональная оболочка заключает в кавычки любой массив arg, который вы ей передаете, и увеличивает его вывод для каждого повторяемого аргумента.
Вот это с несколькими аргументами:
ВЫХОД
Это вывод, из
dash
которого обычно вывод с одинарными кавычками, как обычно'"'"'
.bash
сделал бы'\''
.Замена выделенного, непустого, ненулевого байта другим одиночным байтом, вероятно, может быть выполнена быстрее всего в любой оболочке POSIX с помощью
$IFS
и$*
.ВЫХОД
Там я просто
printf
так, чтобы вы могли видеть это, но, конечно, если бы я сделал:... вместо
printf
команды$var
значение «s будет то , что вы видите на выходе там.Когда я
set -f
даю команду оболочке не использовать глобус - в случае, если строка содержит символы, которые могут быть истолкованы как шаблоны глобуса. Я делаю это потому, что синтаксический анализатор оболочек расширяет шаблоны глобуса после того, как он выполняет разбиение поля на переменные. Globbing может быть снова включен, какset +f
. В целом - в сценариях - я считаю полезным установить мой взрыв следующим образом:И затем, чтобы явно разрешить глобализацию с
set +f
любой строкой, которую я мог бы хотеть.Разделение полей происходит на основе символов в
$IFS
.Есть два вида
$IFS
значений -$IFS
пробельные и$IFS
непробельные.$IFS
пробельных (пробел, табуляция, перевод строки) с разделителями полей указаны в Elide по последовательности к одному полю (или вообще ничего , если они не предшествуют что - то еще) - так ...Но все остальные указаны для оценки по одному полю для каждого вхождения - они не усекаются.
Все расширения переменных по умолчанию являются
$IFS
массивами данных с разделителями - они разделяются на отдельные поля в соответствии с$IFS
. Когда вы"
цитируете единицу, вы переопределяете это свойство массива и оцениваете его как одну строку.Поэтому, когда я делаю ...
Я устанавливаю массив аргументов оболочки для множества
$IFS
полей с разделителями, созданных$var
расширением. Когда он развернут, его составляющие значения для символов, содержащихся в нем$IFS
, теряются - теперь они являются только разделителями полей - так и есть\0NUL
."$*"
- как и другие переменные-расширения в двойных кавычках - также переопределяет свойства разделения поля$IFS
. Но, кроме того , он заменяет первый байт в$IFS
каждом поле с разделителями в"$@"
. Таким образом, потому что"
было первое значение во$IFS
всех последующих разделителей стать"
в"$*"
. И"
не нужно быть там,$IFS
когда ты его разделяешь. Вы можете изменить$IFS
послеset -- $args
того, как другое значение целиком и его новый первый байт будет затем отображаться для полевых разделителей"$*"
. Более того, вы можете полностью удалить их следы, например:ВЫХОД
источник
tr
в любой оболочке, но разница вbash
данном${var//$c/$newc/}
случае сомнительна . Я ожидаю, что даже в этом случае это будет быстрее с некоторым запасом, но я обычно не беспокоюсь об этом, потому что для этого материала я всегда используюdash
- который быстрее на порядок во всех отношениях. И так сложно сравнивать.bash
,time (IFS=\"\'`; set -- $var; printf %s "$*")
иtime (var=${var//\'`/\"/})
оба приводят к0.0000s
результатам для всех полей. Я что-то делаю не так, как вы думаете? Там должна быть обратная косая черта перед обратной цитатой, но я не знаю, как вставить обратную цитату в поле кода комментария.