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


78

Ich schreibe ein Skript unter UNIX, in dem ich überprüfen muss, ob das erste Zeichen in einer Zeichenfolge "/" ist, und wenn ja, verzweigen.

Zum Beispiel habe ich eine Zeichenfolge:

/some/directory/file

Ich möchte, dass dies 1 zurückgibt und:

server@10.200.200.20:/some/directory/file

0 zurückgeben.


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

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

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="server@10.200.200.20:/some/directory/file"
$ [ ${foo:0:1} == "/" ] && echo 1 || echo 0
0

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?


Warum das printf? Wäre das, weil echoLeerzeichen entfernt würden?
Alexis Wilke

@AlexisWilke echohat ein von der Implementierung definiertes Verhalten bei
Escape-Aktionen.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.