Sprawdź długość zmiennej


27

Muszę zweryfikować długość odczytu zmiennej (mój limit skryptu do pięciu wstawionych znaków), myślę o czymś takim:

#!/bin/bash
read string
check=${#string}
echo $check
if [ $check -ge 5 ]; then echo "error" ; exit
else echo "done"
fi

czy istnieje bardziej „eleganckie” rozwiązanie?


1
Twój skrypt działa poprawnie w standardowym POSIX /bin/sh. Powinieneś rozważyć zmianę linii shebang na, #!/bin/shaby była bardziej przenośna i działała w środowiskach, w których bash nie jest dostępny. Ponadto /bin/shmoże być bardziej lekką powłoką, taką jak deska rozdzielcza, która nie jest obciążona funkcjami przeznaczonymi do użytku interaktywnego.
Celada,

@Celada, prawda choć w tym przypadku dashjest ${#string}nie daje długość w bajtach zamiast znaków.
Stéphane Chazelas,

Odpowiedzi:


43

Bardziej elegancki? Nie

Krótszy? Tak :)

#!/bin/bash
read string
if [ ${#string} -ge 5 ]; then echo "error" ; exit
else echo "done"
fi

A jeśli nie masz problemu z zamianą większej elegancji na korzyść bycia krótszym, możesz mieć skrypt z 2 liniami mniej:

#!/bin/bash
read string
[ ${#string} -ge 5 ] && echo "error" || echo "done"

Możesz użyć podwójnych nawiasów, jeśli uważasz, że jest to bezpieczniejsze. Wyjaśnienie tutaj .


3

Alternatywa kompatybilna z Bourne ( ${#string}jest POSIX, ale nie Bourne (nie jest tak, że w dzisiejszych czasach najprawdopodobniej spotkasz pocisk Bourne)):

case $string in
  ?????*) echo >&2 Too long; exit 1;;
       *) echo OK
esac

Zauważ, że dla obu ${#string}i to ????, czy będzie to liczba bajtów czy znaków, zależy od powłoki. Ogólnie (i jest to wymagane przez POSIX), jest to liczba znaków. Ale dla niektórych takich powłok dashnie są one rozpoznawane w wielu bajtach, zamiast tego będą to bajty.

Za pomocą (w ustawieniach regionalnych UTF-8) mkshmusisz set -o utf8-modezrozumieć znaki wielobajtowe:

$ string=€€€ bash -c 'echo "${#string}"'
3
$ string=€€€ dash -c 'echo "${#string}"'
9
$ string=€€€ mksh -c 'echo "${#string}"'
9
$ string=€€€ mksh -o utf8-mode -c 'echo "${#string}"'
3
$ locale charmap
UTF-8

poza tematem, ale echo Too longróżni się pod maską odecho 'Too long'
Steven Penny,

A jeśli po prostu wydrukujesz, gdy będzie „za długi”, mogę jeszcze bardziej skompaktować moją ifopcję :)

2
@StevenPenny echo Too longprzekazuje dwa argumenty ( Tooi long), do echoktórych dane echowyjściowe są oddzielone spacją (i po których następuje nowa linia), natomiast wewnątrz przekazujemy echo 'Too long'jeden Too longargument, do echoktórego wyświetla się po nim nowa linia. Jest to więc funkcjonalnie równoważny.
Stéphane Chazelas,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.