So prüfen Sie, ob eine Zeichenfolge in bash einen Teilstring enthält

Ich habe eine Zeile in Bash:

 string="My string" 

Wie kann man überprüfen, ob es eine andere Zeile enthält?

 if [ $string ?? 'foo' ]; then echo "It there!" fi 

Wo ?? - mein unbekannter Operator Verwenden Sie Echo und grep ?

 if echo "$string" | grep 'foo'; then echo "It there!" fi 

Es sieht etwas unbeholfen aus.

1952
23 окт. Set Davidsheldon 23. Okt. 2008-10-23 15:37 2008 um 15:37 Uhr 2008-10-23 15:37 Uhr
@ 22 Antworten

Sie können die Marcus-Antwort (* Wildcards) außerhalb der case-Anweisung verwenden, wenn Sie doppelte Klammern verwenden:

 string='My long string' if [[ $string == *"My long"* ]]; then echo "It there!" fi 

Beachten Sie, dass Leerzeichen im Nadelseil zwischen Anführungszeichen stehen müssen und Wildcards * außerhalb stehen müssen.

2795
23 окт. Antwort von Adam Bellaire am 23. Oktober 2008-10-23 15:55 08 um 15:55 2008-10-23 15:55

Wenn Sie einen Ansatz für reguläre Ausdrücke bevorzugen:

border=0
 string='My string'; if [[ $string =~ .*My.* ]] then echo "It there!" fi 
420
23 окт. Antwort von Matt Tardiff 23. Oktober. 2008-10-23 23:10 08 um 23:10 Uhr 2008-10-23 23:10

Ich bin nicht sicher, ob die if -Anweisung verwendet wird. Mit dem Argument case können Sie jedoch einen ähnlichen Effekt erzielen:

 case "$string" in *foo*) # Do stuff ;; esac 
262
23 окт. Antwort von Marcus Griep 23. Okt. 2008-10-23 15:47 08 um 15.47 Uhr 2008-10-23 15:47

Kompatible Antwort

Da es bereits viele Antworten mit Bash-spezifischen Funktionen gab, gibt es eine Möglichkeit, mit mehr weißen Funktionen zu arbeiten, z. B. mit :

 [ -z "${string##*$reqsubstr*}" ] 

In der Praxis kann dies Folgendes ergeben:

 string='echo "My string"' for reqsubstr in 'o "M' 'alt' 'str';do if [ -z "${string##*$reqsubstr*}" ] ;then echo "String '$string' contain substring: '$reqsubstr'." else echo "String '$string' don't contain substring: '$reqsubstr'." fi done 

Es wurde in , , und ash (busybox) getestet und das Ergebnis ist immer:

 myfunc() { reqsubstr="$1" shift string="$@" if [ -z "${string##*$reqsubstr*}" ] ;then echo "String '$string' contain substring: '$reqsubstr'."; else echo "String '$string' don't contain substring: '$reqsubstr'." fi } 

Dann:

 $ myfunc 'o "M' echo "My String" String 'echo My String' don't contain substring: 'o "M'. $ myfunc 'o "M' echo \"My String\" String 'echo "My String"' contain substring: 'o "M'. 

Einfache funktion

Dies wurde in , und natürlich getestet:

 $ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi no $ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi yes 

... oder, wenn die abgelegte Zeichenfolge leer sein kann, wie in @Sjlver angegeben, sieht die Funktion folgendermaßen aus:

 stringContain() { [ -z "${2##*$1*}" ]  [ -z "$1" -o -n "$2" ]; } 

oder, wie in Adrian Günthers Kommentar vorgeschlagen , -o switche zu vermeiden:

 stringContain() { [ -z "${2##*$1*}" ]  { [ -z "$1" ] || [ -n "$2" ] ;} ; } 

Mit leeren Zeilen:

 $ if stringContain '' ''; then echo yes; else echo no; fi yes $ if stringContain 'o "M' ''; then echo yes; else echo no; fi no 
167
09 дек. Die Antwort ist gegeben F. Hauri 09 Dez. 2013-12-09 02:06 '13 am 2:06 2013-12-09 02:06

Sie müssen sich daran erinnern, dass das Shell-Skript kleiner als die Sprache ist und mehr Befehle enthält. Intuitiv denken Sie, dass diese "Sprache" ver>if mit [ oder [[ . Bei beiden Befehlen handelt es sich einfach um Befehle, die den Beendigungsstatus zurückgeben, der auf Erfolg oder Misserfolg hinweist (wie bei jedem anderen Befehl). Aus diesem Grund würde ich grep , nicht die [ .

Folge einfach:

 ## Instead of this filetype="$(file -b "$1")" if grep -q "tar archive" <<<"$filetype"; then #... ## Simply do this if file -b "$1" | grep -q "tar archive"; then #... 

Die Option -q dass bei grep nichts ausgegeben wird, da nur der Rückkehrcode benötigt wird. <<< zwingt die Shell, das nächste Wort zu erweitern und als Eingabe für den Befehl zu verwenden, eine einzeilige Version des Dokuments << (Ich bin nicht sicher, ob dies ein Standard oder ein Bashmus ist).

127
27 окт. Antwort von Mark Baker 27. Oktober 2008-10-27 17:57 08 um 17:57 2008-10-27 17:57

Die akzeptierte Antwort ist besser, aber da es mehr als einen Weg gibt, dies zu tun, gibt es eine andere Lösung:

 if [ "$string" != "${string/foo/}" ]; then echo "It there!" fi 

${var/search/replace} ist $var wenn die erste Instanz der search durch replace ersetzt wird replace wenn sie gefunden wird (es ändert sich nicht $var ). Wenn Sie versuchen, foo durch nichts zu ersetzen, und der String sich geändert hat, wurde offensichtlich foo gefunden.

78
23 окт. Die Antwort wird von ephemient am 23. Oktober gegeben 2008-10-23 17:35 08 um 17:35 Uhr 2008-10-23 17:35 Uhr

Es gibt also viele nützliche Lösungen für die Frage - aber was ist schneller / verwendet die kleinste Ressource?

Wiederholte Tests mit diesem Rahmen:

 /usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done' 

TEST jedes Mal ersetzen:

 [[ $b =~ $a ]] 2.92user 0.06system 0:02.99elapsed 99%CPU [ "${b/$a//}" = "$b" ] 3.16user 0.07system 0:03.25elapsed 99%CPU [[ $b == *$a* ]] 1.85user 0.04system 0:01.90elapsed 99%CPU case $b in *$a):;;esac 1.80user 0.02system 0:01.83elapsed 99%CPU doContain $a $b 4.27user 0.11system 0:04.41elapsed 99%CPU 

(doContain war eine Antwort auf F. Khoury)

Und für ein Kichern:

 echo $b|grep -q $a 12.68user 30.86system 3:42.40elapsed 19%CPU !ouch! 

Somit gewinnt die einfache Ersatzoption im erweiterten Test oder Fall prädikativ. Der Fall ist tragbar.

Pipelines bis zu 100.000 Grad sind vorhersehbar schmerzhaft! Die alte Regel zur Verwendung externer Dienstprogramme ist nicht erforderlich.

38
27 авг. Antwort von Paul Hedderly 27. Aug. 2014-08-27 22:42 14 um 22:42 Uhr 2014-08-27 22:42

Es funktioniert auch:

 if printf -- '%s' "$haystack" | egrep -q -- "$needle" then printf "Found needle in haystack" fi 

Und ein negativer Test:

 if ! printf -- '%s' "$haystack" | egrep -q -- "$needle" then echo "Did not find needle in haystack" fi 

Ich denke, dieser Stil ist etwas klassischer, weniger abhängig von den Eigenschaften der Bash-Shell.

Das Argument -- reine POSIX-Paranoia, die zum Schutz vor Eingabezeilen wie Parametern verwendet wird, z. B. --abc oder -a .

Hinweis In einer geschlossenen Schleife ist dieser Code viel >

24
01 дек. Die Antwort ist kevinarpe 01 Dez. gegeben. 2012-12-01 18:41 '12 am 18:41 2012-12-01 18:41

Wie wäre es damit:

 text=" <tag>bmnmn</tag> " if [[ "$text" =~ "<tag>" ]]; then echo "matched" else echo "not matched" fi 
13
09 февр. Die Antwort ist gegeben Stefan 09 Feb. 2009-02-09 09:15 09 um 09:15 Uhr 2009-02-09 09:15 Uhr

Wie Paulus in seinem Leistungsvergleich sagte:

 if echo "abcdefg" | grep -q "bcdef"; then echo "String contains is true." else echo "String contains is not true." fi 

Es ist POSIX-konform, wie bei "case" $ string "in" von Marcus, aber es ist etwas einfacher zu lesen als die Antwort auf die Anfrage in diesem Fall. Beachten Sie auch, dass dies viel >

10
01 янв. Die Antwort gibt Samuel 01.01 2015-01-01 01:32 15 um 01:32 Uhr 2015-01-01 01:32

Diese Überlaufreaktion im Stapel war die einzige, die Leerzeichen und Bindestriche einfangen konnte:

 # For null cmd arguments checking to_check=' -t' space_n_dash_chars=' -' [[ $to_check == *"$space_n_dash_chars"* ]]  echo found 
9
26 авг. Die Antwort ist gegeben von Yordan Georgiev . 2013-08-26 13:13 '13 am 13:13 2013-08-26 13:13

Einer von ihnen:

 [ $(expr $mystring : ".*${search}.*") -ne 0 ]  echo 'yes' || echo 'no' 
8
11 нояб. Die Antwort wird am 11. November gegeben. 2011-11-11 08:51 11 um 08:51 2011-11-11 08:51

Bash4 +. Hinweis: Verwenden Sie keine Anführungszeichen, werden Probleme verursacht, wenn Wörter Leerzeichen usw. enthalten. Immer in Bash IMO angeben.

Hier einige Beispiele für Bash4 +:

Beispiel 1, markieren Sie "Ja" in der Zeile (Groß- und Kleinschreibung wird nicht berücksichtigt):

  if [[ "${str,,}" == *"yes"* ]] ;then 

Beispiel 2, markieren Sie "Ja" in der Zeile (Groß- und Kleinschreibung wird nicht berücksichtigt):

  if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then 

Beispiel 3, überprüfen Sie "Ja" in der Zeile (Groß- und Kleinschreibung beachten):

  if [[ "${str}" == *"yes"* ]] ;then 

Beispiel 4, aktivieren Sie "Ja" in der Zeile (Groß- und Kleinschreibung beachten):

  if [[ "${str}" =~ "yes" ]] ;then 

Beispiel 5, genaue Übereinstimmung (Groß- und Kleinschreibung beachten):

  if [[ "${str}" == "yes" ]] ;then 

Beispiel 6, exakte Übereinstimmung (Groß- und Kleinschreibung wird nicht berücksichtigt):

  if [[ "${str,,}" == "yes" ]] ;then 

Beispiel 7: genaue Übereinstimmung:

  if [ "$a" = "$b" ] ;then 

Beispiel 8: Der Platzhalter stimmt mit .ext überein (Groß- und Kleinschreibung wird nicht berücksichtigt):

  if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then 

genießen

7
05 окт. Antwort von Mike Q 05 2018-10-05 21:54 '18 um 21:54 2018-10-05 21:54
 [[ $string == *foo* ]]  echo "It there" || echo "Couldn't find" 
7
28 апр. Die Antwort wird von Jahid 28. April gegeben 2015-04-28 22:55 '15 um 22:55 Uhr 2015-04-28 22:55

grep -q ist für diesen Zweck nützlich.

Das gleiche mit awk :

 string="unix-bash 2389" character="@" printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }' 

Fazit:

Nicht gefunden

 string="unix-bash 2389" character="-" printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }' 

Fazit:

Gefunden

Quelle: http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html

4
21 дек. Antwort von Jadu Saikia 21. Dezember 2008-12-21 17:27 08 um 17:27 Uhr 2008-12-21 17:27

Ich mag sed

 substr="foo" nonsub="$(echo "$string" | sed "s/$substr//")" hassub=0 ; [ "$string" != "$nonsub" ]  hassub=1 

Änderung, Logik:

  • Verwenden Sie sed, um eine Instanz eines Teilstrings aus einem String zu entfernen.

  • Wenn sich die neue Zeichenfolge von der alten Zeichenfolge unterscheidet, gibt es eine Teilzeichenfolge

4
03 марта '16 в 22:12 2016-03-03 22:12 Die Antwort wird gegeben März 03 '16 um 10:12 2016-03-03 22:12

Mein .bash_profile und wie ich grep verwendet habe, wenn PATH meine 2 bin-Verzeichnisse enthalten hat, fügen Sie sie nicht hinzu

 # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi U=~/.local.bin:~/bin if ! echo "$PATH" | grep -q "home"; then export PATH=$PATH:${U} fi 
4
14 янв. Antwort von Leslie Satenstein 2017-01-14 08:36 '17 am 08:36 2017-01-14 08:36

Ich musste diese Funktion oft ausführen, daher verwende ich die Home-Shell-Funktion in meiner .bashrc Funktion, sodass ich sie so oft verwenden kann, wie ich sie brauche, mit einem leicht zu merkenden Namen:

 function stringinstring() { case "$2" in *"$1"*) return 0 ;; esac return 1 } 

Um zu prüfen, ob $string1 (zB abc) in $string2 (zB 123abcABC) enthalten ist, muss ich nur die stringinstring "$string1" "$string2" und den Rückgabewert überprüfen

 stringinstring "$str1" "$str2"  echo YES || echo NO 
3
01 июля '12 в 14:31 2012-07-01 14:31 Die Antwort wird von Kurt Pfeifle am 01. Juli '12 um 14:31 Uhr 2012-07-01 14:31 gegeben

Genaue Übereinstimmung der Wörter:

 string='My long string' exactSearch='long' if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2> then echo "It there" fi 
2
10 нояб. Antwort von Eduardo Cuomo 10 Nov. 2016-11-10 17:56 '16 um 17:56 Uhr 2016-11-10 17:56

Probieren Sie oobash aus - dies ist eine String-OO-Bibliothek für Bash 4. Sie unterstützt deutsche Umlaute. Es ist in Bash geschrieben. Es stehen viele Funktionen zur Verfügung: -isAlpha , -isAscii , -isDigit , -isEmpty , -isHexDigit , -isLowerCase -swapCase , -toLowerCase , -toString , -toUpperCase , -trim und -zfill .

Sehen Sie sich ein Beispiel an:

 [Desktop]$ String a testXccc [Desktop]$ a.contains tX true [Desktop]$ a.contains XtX false 

Oobash ist auf Sourceforge.net verfügbar .

2
27 авг. Antwort an andreas 27 aug. 2010-08-27 22:19 '10 am 10:19 PM 2010-08-27 22:19

Ich benutze diese Funktion (eine Abhängigkeit ist nicht enthalten, aber es ist offensichtlich). Er besteht die unten gezeigten Tests. Wenn die Funktion einen Wert> 0 zurückgibt, wurde die Zeichenfolge gefunden. Sie können auch einfach 1 oder 0 zurückgeben.

 function str_instr { # Return position of ```str``` within ```string```. # >>> str_instr "str" "string" # str: String to search for. # string: String to search. typeset str string x # Behavior here is not the same in bash vs ksh unless we escape special characters. str="$(str_escape_special_characters "${1}")" string="${2}" x="${string%%$str*}" if [[ "${x}" != "${string}" ]]; then echo "${#x} + 1" | bc -l else echo 0 fi } function test_str_instr { str_instr "(" "'foo@host (dev,web)'" | assert_eq 11 str_instr ")" "'foo@host (dev,web)'" | assert_eq 19 str_instr "[" "'foo@host [dev,web]'" | assert_eq 11 str_instr "]" "'foo@host [dev,web]'" | assert_eq 19 str_instr "a" "abc" | assert_eq 1 str_instr "z" "abc" | assert_eq 0 str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7 str_instr "a" "" | assert_eq 0 str_instr "" "" | assert_eq 0 str_instr " " "Green Eggs" | assert_eq 6 str_instr " " " Green " | assert_eq 1 } 
1
11 апр. Antwort von Ethan Post 11. April 2018-04-11 05:09 18 um 17:09 Uhr 2018-04-11 05:09

Die Erweiterung der Frage wurde hier beantwortet spravaw.site.site/questions/2769 / ...

Diese Lösung arbeitet mit Sonderzeichen:

 # contains(string, substring) # # Returns 0 if the specified string contains the specified substring, # otherwise returns 1. contains() { string="$1" substring="$2" if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then return 0 # $substring is in $string else return 1 # $substring is not in $string fi } contains "abcd" "e" || echo "abcd does not contain e" contains "abcd" "ab"  echo "abcd contains ab" contains "abcd" "bc"  echo "abcd contains bc" contains "abcd" "cd"  echo "abcd contains cd" contains "abcd" "abcd"  echo "abcd contains abcd" contains "" ""  echo "empty string contains empty string" contains "a" ""  echo "a contains empty string" contains "" "a" || echo "empty string does not contain a" contains "abcd efgh" "cd ef"  echo "abcd efgh contains cd ef" contains "abcd efgh" " "  echo "abcd efgh contains a space" contains "abcd [efg] hij" "[efg]"  echo "abcd [efg] hij contains [efg]" contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]" contains "abcd *efg* hij" "*efg*"  echo "abcd *efg* hij contains *efg*" contains "abcd *efg* hij" "d *efg* h"  echo "abcd *efg* hij contains d *efg* h" contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*" 
0
02 февр. Antwort von Alex.Designworks 02 Feb. 2019-02-02 09:03 '19 am 9:03 2019-02-02 09:03

Weitere Fragen zu Tags: oder Eine Frage stellen