Wenn Sie zufällig nur versuchen, Angebote für die Wiederverwendung der Shell zu verarbeiten, können Sie dies tun, ohne sie zu entfernen, und es ist auch denkbar einfach:
aq() { sh -c 'for a do
alias "$((i=$i+1))=$a"
done; alias' -- "$@"
}
Diese Funktionsshell setzt ein beliebiges von Ihnen übergebenes arg-Array in Anführungszeichen und erhöht seine Ausgabe pro iterierbarem Argument.
Hier ist es mit ein paar Argumenten:
aq \
"here's an
ugly one" \
"this one is \$PATHpretty bad, too" \
'this one```****```; totally sucks'
AUSGABE
1='here'"'"'s an
ugly one'
2='this one is $PATHpretty bad, too'
3='this one```****```; totally sucks'
Diese Ausgabe ist eine Ausgabe, dash
die in der Regel in sicheren Anführungszeichen steht '"'"'
. bash
würde tun '\''
.
Das Ersetzen einer Auswahl einzelner Bytes, die keine Leerzeichen oder Nullen enthalten, durch ein anderes Byte ist in einer POSIX-Shell mit $IFS
und wahrscheinlich am schnellsten möglich $*
.
set -f; IFS=\"\'\`; set -- $var; printf %s "$*"
AUSGABE
"some ""crazy """"""""string ""here
Dort habe ich es einfach printf
so, dass man es sehen kann, aber natürlich, wenn ich es getan hätte:
var="$*"
... und nicht der Wert des printf
Befehls $var
, den Sie dort in der Ausgabe sehen.
Wenn ich set -f
die Shell anweise, nicht zu globieren - falls die Zeichenfolge Zeichen enthält, die als Glob-Muster ausgelegt werden könnten. Ich mache das, weil der Shells-Parser Glob-Muster erweitert, nachdem er die Feldaufteilung für Variablen durchgeführt hat. Globbing kann wie wieder aktiviert werden set +f
. Im Allgemeinen - in Skripten - finde ich es nützlich, meinen Knall wie folgt zu setzen:
#!/usr/bin/sh -f
Und dann explizit das Globbing mit einer set +f
beliebigen Zeile aktivieren , die ich haben möchte.
Die Feldaufteilung erfolgt anhand der Zeichen in $IFS
.
Es gibt zwei Arten von $IFS
Werten - $IFS
Leerzeichen und $IFS
Nicht-Leerzeichen. $IFS
Durch Leerzeichen (Leerzeichen, Tabulatoren, Zeilenvorschübe) getrennte Felder werden so angegeben, dass sie nach der Reihenfolge in ein einzelnes Feld zerlegt werden (oder gar nicht, wenn sie keinem anderen Feld vorangehen) - also ...
IFS=\ ; var=' '; printf '<%s>' $var
<>
Alle anderen sind jedoch so spezifiziert, dass sie pro Vorkommen zu einem einzigen Feld ausgewertet werden - sie werden nicht abgeschnitten.
IFS=/; var='/////'; printf '<%s>' $var
<><><><><>
Alle Variablenerweiterungen sind standardmäßig durch $IFS
Trennzeichen getrennte Datenfelder $IFS
. Sie werden in separate Felder aufgeteilt . Mit "
-quote one überschreiben Sie diese Array-Eigenschaft und werten sie als einzelne Zeichenfolge aus.
Also, wenn ich es tue ...
IFS=\"\'\`; set -- $var
Ich setze das Argumentarray der Shell auf die vielen $IFS
begrenzten Felder, die durch $var
die Erweiterung generiert werden . Wenn es seine konstituierenden Werte für die Zeichen erweitert enthalten in $IFS
sind verloren - sie sind jetzt nur Feldtrenn - sie sind \0NUL
.
"$*"
- Wie bei anderen Variablenerweiterungen in doppelten Anführungszeichen - werden auch die feldaufteilenden Eigenschaften von überschrieben $IFS
. Aber zusätzlich , ersetzt es das erste Byte in $IFS
für jedes Feld begrenzt in "$@"
. Also da "
wurde der erste Wert in $IFS
allen nachfolgenden Begrenzern "
in "$*"
. Und das "
muss auch nicht sein, $IFS
wenn Sie es teilen. Sie können $IFS
after set -- $args
vollständig auf einen anderen Wert ändern , und das neue erste Byte wird dann für die Feldbegrenzer in angezeigt "$*"
. Außerdem können Sie alle Spuren wie folgt entfernen:
set -- $var; IFS=; printf %s "$*"
AUSGABE
some crazy string here
tr
. BASHs PE ist gut, aber in diesem Fall ist tr viel schneller. zBecho "$OUTPUT" | tr -dc '[[:alpha:]]'
weil Sie nur alphanumerische Zeichen haben möchten