Jeśli przypadkowo próbujesz poradzić sobie z cytatami dotyczącymi ponownego użycia powłoki, możesz to zrobić bez usuwania ich, a to również jest bardzo proste:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Ta funkcja powłoki cytuje każdą tablicę arg, którą jej podajesz, i zwiększa jej wynik na iterowalny argument.
Oto kilka argumentów:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
WYNIK
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
To wyjście, z dash
którego typowo bezpieczne cytaty zawierają pojedyncze cytaty '"'"'
.bash
zrobiłby '\''
.
Zastąpienie wyboru pojedynczych bajtów niepustych białych znakami o wartości innej niż null innym pojedynczym bajtem można prawdopodobnie zrobić najszybciej w dowolnej powłoce POSIX za pomocą $IFS
i $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
WYNIK
"some ""crazy """"""""string ""here
Tam właśnie printf
to widzę, ale oczywiście, gdybym to zrobił:
var="$*"
... zamiast printf
polecenia$var
„s wartość byłaby co widać w tam wyjście.
Kiedy set -f
instruuję powłokę, aby nie globowała - w przypadku gdy łańcuch zawiera znaki, które można by interpretować jako wzorce globu. Robię to, ponieważ parser powłok rozszerza wzorce globu po dokonaniu podziału pól na zmienne. globbing może być ponownie włączony jak set +f
. Ogólnie rzecz biorąc - w skryptach - przydatne jest ustawienie huku w następujący sposób:
#!/usr/bin/sh -f
A następnie, aby jawnie włączyć globowanie z set +f
dowolną linią, której bym tego chciał.
Podział pola następuje na podstawie znaków w $IFS
.
Istnieją dwa rodzaje $IFS
wartości - $IFS
białe znaki i $IFS
inne znaki. $IFS
spacje (spacja, tabulator, nowa linia) pola rozdzielane są określane tak, aby następowały po nich sekwencje do pojedynczego pola (lub wcale, jeśli nie poprzedzają czegoś innego) - więc ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Ale wszystkie inne są określone, aby oceniać do jednego pola na wystąpienie - nie są obcinane.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Wszystkie rozszerzenia zmiennych są domyślnie $IFS
ograniczonymi tablicami danych - są one podzielone na osobne pola zgodnie z $IFS
. Kiedy ty"
cytujesz jedną, zastępujesz tę właściwość tablicy i oceniasz ją jako pojedynczy ciąg.
Więc kiedy to zrobię ...
IFS=\"\'\`; set -- $var
Ustawiam tablicę argumentów powłoki na wiele $IFS
rozdzielanych pól generowanych przez $var
rozszerzenie. Po rozwinięciu jego wartości składowe dla zawartych w nim znaków $IFS
są tracone - są one teraz tylko separatorami pól - są\0NUL
.
"$*"
- podobnie jak inne podwójnie cytowane rozwinięcia zmiennych - również zastępuje właściwości podziału pola na $IFS
. Ale dodatkowo zastępuje pierwszy bajt w $IFS
każdym rozdzielanym polu w "$@"
. Tak, ponieważ "
był pierwszy wartość $IFS
wszystkich kolejnych ograniczniki stać "
w "$*"
. I "
nie trzeba też być $IFS
przy podziale. Można zmieniać $IFS
po set -- $args
innej wartości w całości i jego nowy pierwszy bajt by następnie pokazać się na ograniczniki polowych w "$*"
. Co więcej, możesz całkowicie usunąć wszystkie ich ślady:
set -- $var; IFS=; printf %s "$*"
WYNIK
some crazy string here
tr
. PEH BASH jest dobry, ale w tym przypadku tr jest znacznie szybszy. np.echo "$OUTPUT" | tr -dc '[[:alpha:]]'
ponieważ chcesz mieć tylko alfanumeryczne