2009-09-24 11 views
17

powiedzieć ciąg może być jak "a b" "c" "d", jak mogę sprawdzić, czy istnieje pojedynczy/podwójny cudzysłów i spacja zawarte w ciągu?jak sprawdzić, czy ciąg ma spacje w powłoce bash

+0

Dlaczego chcesz to zrobić? Jeśli próbujesz, powiedzmy, sprawdzić "nieprawidłową" nazwę pliku, możesz zamiast tego naprawić skrypt, aby obsługiwał nazwy plików ze spacjami lub cudzysłowami. Na przykład. –

+0

Czy chcesz powiedzieć, że chcesz wiedzieć, że: a) istnieje pojedynczy/podwójny cudzysłów wokół przestrzeni b) pojedynczy/podwójny cytat wraz z spacja c) coś zupełnie innego od tego? – ezpz

+0

Wystarczy sprawdzić, czy ciąg ma jakąkolwiek pojedynczą wycenę i czy ma jakąś przestrzeń – derrdji

Odpowiedz

20
case "$var" in 
    *\ *) 
      echo "match" 
      ;; 
     *) 
      echo "no match" 
      ;; 
esac 
+1

Jestem dziurkaczem, ale nie musisz cytować $ var. – Idelic

+0

@Idelic, a co jeśli zmieniono $ var? – Will

+0

To jest w porządku bez cytatów, wydrukuje "brak dopasowania". – Idelic

1

Jak o podobnym podejściu do:

$ A="some string"; echo $A | grep \ | wc -l 
1 
$ A="somestring"; echo $A | grep \ | wc -l 
0 

?

6
string="a b '' c '' d" 
if [ "$string" == "${string//[\' ]/}" ] 
then 
    echo did not contain space or single quote 
else 
    echo did contain space or single quote 
fi 
4

przenośny sposób to zrobić z grep:

S="a b '' c '' d" 
if echo $S | grep -E '[ "]' >/dev/null 
then 
    echo "It's a match" 
fi 

... nieco brzydki, ale gwarantowane do pracy wszędzie.

+1

Z opcją '-q' w grep,'>/dev/null' nie jest już potrzebny. Trochę ładniej. – Ray

21

Można użyć wyrażeń regularnych w bash:

string="a b '' c '' d" 
if [[ "$string" =~ \ |\' ]] # slightly more readable: if [[ "$string" =~ (|\') ]] 
then 
    echo "Matches" 
else 
    echo "No matches" 
fi 

Edit:

Ze względów wyżej oczywistych, to lepiej umieścić regex w zmiennej:

pattern=" |'" 
if [[ $string =~ $pattern ]] 

I cytowania nie są konieczne w nawiasach kwadratowych. Nie można ich użyć po prawej stronie lub wyrażenie regularne zostaje zmienione na ciąg literowy.

+0

najczystszy IMO, dla mnie dodałem także kartę, ale wygląda na nieco funky, bo musiałem wrzucić dolara-cytat tam "wzór =" | "" $ "| \ t'" - czy istnieje czystszy sposób? – nhed

+1

@nhed: W przypadku pojedynczych znaków można użyć wzoru znaków zamiast alternatywnego znaku potoku. Może to być nieco mniej brzydki: 'pattern = $ '[\' \ t] ''. Możesz także użyć zmiennej: 'tab = $ '\ t'; pattern = "| '| $ tab" 'lub literalna zakładka (która nie jest dobra dla czytelności), wpisując ją za pomocą Ctrl-V-Tab. –

1
function foo() { 
    echo "String: $*" 
    SPACES=$(($#-1)) 
    echo "Spaces: $SPACES" 
    QUOTES=0 
    for i in $*; do 
     if [ "$i" == "'" ]; then 
      QUOTES=$((QUOTES+1)) 
     fi 
    done 
    echo "Quotes: $QUOTES" 
    echo 
} 

S="string with spaces" 
foo $S 
S="single' 'quotes" 
foo $S 
S="single '' quotes" 
foo $S 
S="single ' ' quotes" 
foo $S 

plony:

String: string with spaces 
Spaces: 2 
Quotes: 0 

String: single' 'quotes 
Spaces: 1 
Quotes: 0 

String: single '' quotes 
Spaces: 2 
Quotes: 0 

String: single ' ' quotes 
Spaces: 3 
Quotes: 2 
7
[[ "$str" = "${str%[[:space:]]*}" ]] && echo "no spaces" || echo "has spaces" 
+1

Zauważ, że to nie wykrywa tabulatorów ani linii prostych, dla tych, którzy są ciekawi –

0

Zastanawiam się dlaczego nikt nie wspomniał o [: space:] ustawiony. Zwykle nie tylko interesuje Cię wykrywanie charakteru przestrzeni. Często potrzebuję wykryć dowolną białą przestrzeń, np. PATKA. Przykład "grep" będzie wyglądał następująco:

$ echo " " | egrep -q "[:space:]" && echo "Has no Whitespace" || echo "Has Whitespace" 
Has Whitespace 
$ echo "a" | egrep -q "[:space:]" && echo "Has no Whitespace" || echo "Has Whitespace" 
Has no Whitespace 
+0

Dla zainteresowanych tym rozwiązaniem, mój 'grep' informuje mnie, że' składnia klasy postaci jest [[: spacja:]], nie [: spacja: ] '. W przeciwnym razie doskonałe rozwiązanie! – jdferreira

+0

Ponieważ pytanie jest oznaczone jako "bash", nie trzeba uruchamiać innego procesu tylko po to, aby przetestować ciąg znaków: "case" $ String "in * [[: space:]] *) echo" match ";; esac' –

Powiązane problemy