Якщо, за випадковості, ви просто намагаєтеся обробити цитати для повторного використання іонної оболонки, тоді ви можете це зробити, не виймаючи їх, і це теж просто:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Ця оболонка функції цитує будь-який аргумент масиву, який ви йому передаєте, і збільшує його вихід на ітерабельний аргумент.
Ось це з кількома аргументами:
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
було б те, що ви бачите у висновку там.
Коли я set -f
доручаю оболонці не глобувати - на випадок, якщо рядок містить символи, які можуть бути розроблені як шаблони глобуса. Я роблю це через те, що аналізатор оболонок розширює глобальні шаблони після того, як він здійснює розбиття поля на змінні. глобус можна повторно включити, як set +f
. Взагалі - в сценаріях - я вважаю корисним встановити свій удар так:
#!/usr/bin/sh -f
А потім явно включити підстановка з set +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
після set -- $args
того, як інше значення цілком і його новий перший байт буде потім відображатися для польових роздільників "$*"
. Більше того, ви можете видалити всі їх сліди як:
set -- $var; IFS=; printf %s "$*"
ВИХІД
some crazy string here
tr
. ПЕ на BASH хороший, але в цьому випадку tr набагато швидше. наприклад,echo "$OUTPUT" | tr -dc '[[:alpha:]]'
оскільки ви хочете мати лише буквено-цифрові слова