Wie überprüfe ich das erste Zeichen in einer Zeichenfolge in der Bash- oder UNIX-Shell?

Antworten:

138

Viele Möglichkeiten, dies zu tun. Sie können Platzhalter in doppelten Klammern verwenden:

str="/some/directory/file"
if [[ $str == /* ]]; then echo 1; else echo 0; fi

Sie können die Teilzeichenfolgenerweiterung verwenden:

if [[ ${str:0:1} == "/" ]] ; then echo 1; else echo 0; fi

Oder eine Regex:

if [[ $str =~ ^/ ]]; then echo 1; else echo 0; fi
user000001
quelle
16
Verwenden Sie zu kurz : ${str::1}.
Kenorb
16

Betrachten Sie auch die case-Anweisung, die mit den meisten sh-basierten Shells kompatibel ist:

case $str in
/*)
    echo 1
    ;;
*)
    echo 0
    ;;
esac
konsolebox
quelle
1
Ich dachte, Glob *passt nur zu einer einzelnen Pfadkomponente, niemals über Schrägstriche hinweg/
user1011471
1
Das relevante POSIX-Zitat lautet: pubs.opengroup.org/onlinepubs/9699919799/utilities/… "Case Conditional Construct" -Satz "entspricht dem ersten von mehreren Mustern (siehe
Mustervergleichsnotation
1
Auch wenn Sie mit einem übereinstimmen möchten, müssen #Sie Anführungszeichen verwenden. Zum Beispiel : '#'*) echo "found comment";;.
Alexis Wilke
10
$ foo="/some/directory/file"
$ [ ${foo:0:1} == "/" ] && echo 1 || echo 0
1
$ foo="[email protected]:/some/directory/file"
$ [ ${foo:0:1} == "/" ] && echo 1 || echo 0
0
devnull
quelle
5
Downvote! Sie haben vergessen, Ihre Variable in einfachen Klammern anzugeben. foo='*'; [ ${foo:0:1} == "/" ] && echo 1 || echo 0wird diesen Fehler ausgeben bash: [: too many arguments. Verwenden Sie [ "${foo:0:1}" == "/" ] && echo 1 || echo 0oder noch besser[[ ${foo:0:1} == "/" ]] && echo 1 || echo 0
Aleks-Daniel Jakimenko-A.
@ Aleks-DanielJakimenko-A. - Die Antwort von devnull funktioniert fehlerfrei in "GNU Bash, Version 4.3.48 (1) - Release (x86_64-PC-Linux-Gnu) Copyright (C) 2013 Free Software Foundation, Inc."
Craig Hicks
Ihr erster Ausdruck: "Downvote! Sie haben vergessen, Ihre Variable in einfachen Klammern anzugeben." impliziert, dass die in devnulls Antwort eingegebenen Ausdrücke nicht wie bei bash funktionieren. Sie müssen diesen Anfangsausdruck ändern, um Ihren technischen Punkt ordnungsgemäß zu liefern, da er sonst logisch nicht korrekt ist.
Craig Hicks
1
@ Aleks-DanielJakimenko-A. Einen Tippfehler ablehnen? "Ja wirklich?"
Mausy5043
2
@ Mausy5043 es ist kein "Tippfehler", es ist fehlerhaft und falsch.
Aleks-Daniel Jakimenko-A.
5

cut -c1

Dies ist POSIX und caseextrahiert im Gegensatz zum eigentlichen Zeichen das erste Zeichen, wenn Sie es für später benötigen:

myvar=abc
first_char="$(printf '%s' "$myvar" | cut -c1)"
if [ "$first_char" = a ]; then
  echo 'starts with a'
else
  echo 'does not start with a'
fi

awk substr ist eine andere POSIX, aber weniger effiziente Alternative:

printf '%s' "$myvar" | awk '{print substr ($0, 0, 1)}'

printf '%s'Um Probleme mit Escape-Zeichen zu vermeiden: https://stackoverflow.com/a/40423558/895245 Beispiel:

myvar='\n'
printf '%s' "$myvar" | cut -c1

Ausgänge \wie erwartet.

${::} scheint nicht POSIX zu sein.

Siehe auch: Wie extrahiere ich die ersten beiden Zeichen einer Zeichenfolge in Shell-Skripten?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
Warum das printf? Wäre das, weil echoLeerzeichen entfernt würden?
Alexis Wilke
@AlexisWilke echohat ein von der Implementierung definiertes Verhalten bei
Escape-Aktionen.