Jak napisać skrypt powłoki, który dopasuje podciągi znaków bez rozróżniania wielkości liter do danych wyjściowych polecenia?
shell-script
shell
string
Miguel Roque
źródło
źródło
grep -i
może?bash
nadzbiorem standardu unixsh
. Możesz zacząć od jednego z następujących: | 1 | | 2 | - tylko po to, aby poznać rzeczywisty kontekst.Odpowiedzi:
Najpierw jest prosty przykładowy skrypt, który nie ignoruje wielkości liter:
Spróbuj zmienić łańcuch „witaj” po prawej stronie i nie powinien on już odbijać echa
it works
. Spróbuj zastąpić wybranąecho hello
komendą. Jeśli chcesz zignorować wielkość liter, a żaden ciąg nie zawiera podziału wiersza, możesz użyć grep:Kluczem tutaj jest to, że przekazujesz dane wyjściowe polecenia
grep
.if
Oświadczenie testuje kod zakończenia pierwszej z prawej strony komendy w rurociągu - w tym przypadku grep. Grep kończy się sukcesem tylko wtedy, gdy znajdzie dopasowanie.-i
Opcja grep mówi zignorować sprawę. Opcja mówi się nie emitować wyjście i wyjście po pierwszym meczu. Opcja mówi traktować jako argument ciąg zamiast wyrażenia regularnego.-q
-F
Zauważ, że w pierwszym przykładzie zastosowano bezpośrednie porównania i różne przydatne operatory. Drugi formularz po prostu wykonuje polecenia i testuje ich status wyjścia.
[ expression ]
źródło
==
nie jest POSIX.sh
nie jest dostępnybash
we wszystkich systemach Linux.==
nie jest obsługiwany przezash
(na którymsh
opiera się przynajmniej wiele BSD i pochodnych Debiana) lubposh
, i wymaga cytowania wzsh
. Nie ma sensu podwoić=
.[
to polecenie do testowania. Tutaj nie trzeba rozróżniać między przypisaniem a porównaniem. To różni się w(( a == b ))
porównaniu do(( a = b))
. Używanie==
w skrypcie, który zaczyna się od,#! /bin/sh
jest nieprawidłowe. Jeśli przyjmujeszksh
lubbash
składnia, zaktualizuj#!
odpowiednio.Możesz ustawić rozróżnianie wielkości liter bez rozróżniania wielkości liter
bash
przy użyciu operatora regex,=~
jeśli ustawisznocasematch
opcję powłoki. Na przykładźródło
[[ XYZ == xyz ]] && echo "match"
=>match
Aby wyszukać ciąg znaków z uwzględnieniem wielkości liter, wartość zmiennej
needle
w wartości zmiennejhaystack
:Aby wyszukać ciąg znaków bez rozróżniania wielkości liter, przekonwertuj oba na tę samą wielkość liter.
Zauważ, że
tr
coreutils w GNU nie obsługują wielobajtowych ustawień regionalnych (np. UTF-8). Aby pracować z ustawieniami wielobajtowymi, użyj zamiast tego awk. Jeśli zamierzasz użyć awk, możesz sprawić, że porówna ciąg znaków, a nie tylko konwersję.Funkcja
tr
BusyBox nie obsługuje składni; możesz zamiast tego użyć . BusyBox nie obsługuje ustawień regionalnych innych niż ASCII.[:CLASS:]
tr a-z A-Z
W wersji bash (ale nie sh) w wersji 4.0+ istnieje wbudowana składnia do konwersji wielkości liter i prostsza składnia do dopasowywania ciągów.
źródło
printf | tr
sprawia, że kręci mi się w głowie. Tam, gdzie to możliwe, ograniczaj wywoływanie poleceń do minimum ... biorąc pod uwagę zmienną v, możesz zrobić to samo za pomocąv=$(tr '[:lower:]' '[:upper:]' <<<$v)
. Dla tych, którzy nigdy go nie widzieli,<<<
jest to w zasadzie „zmienna tutaj”, tak jak w<<EOF
przypadku dokumentu tutaj. Nieprintf
bądźecho
chyba że koniecznie musisz to zrobić.<<<
operator: ksh, bash, zsh, ale nie zwykły sh. I jest bardzo zbliżony do potokowaniaprintf
pod względem sposobu działania: istnieje taka sama liczba wywołań dofork
iexecve
(zakładając, żeprintf
jest wbudowany, co ma miejsce w większości popularnych powłok); Różnica polega na tym, że<<<
tworzy plik tymczasowy zamiast używania potoku.<<<
wygodnie jest pisać, ale nie poprawia wydajności.