Mam ciąg będący wynikiem operacji, nad którą nie mam kontroli. Kiedy drukuję tę zmienną za pomocą echo
, otrzymuję:
echo $myvar
hello
Jednak kiedy to zrobię
if [ $myvar = "hello" ]; then
echo they are equal
else
echo they are not equal
fi
Zawsze rozumiem, że nie są równi. Podejrzewam, że dzieje się tak z powodu newline
postaci.
Sznurek zachowuje się również dziwnie. Kiedy robię:
newVAR="this is my var twice: "$myvar$myvar
echo $newVAR
Dostaję:
hellois my var twice: hello
Jak mogę sprawdzić, czy jest to faktycznie spowodowane, newline
a jeśli tak, to go usunąć?
printf '%q\n' "$string"
uzyskać ucieczkową wersję dowolnego łańcucha. Na przykład:printf '%q\n' 'foo\n'
->foo\\n
;printf '%q\n' $'foo\n'
->$'foo\n'
echo $foo
. Róbecho "$foo"
zamiast tego.Odpowiedzi:
Problem polega na tym, że masz osadzony Carriage-Return (CR,
\r
). Powoduje to, że punkt wstawiania tekstu terminala wraca do początku linii, którą drukuje. Dlatego właśnie widzisz „witaj” na początku wiersza w swoim$newVAR
przykładzie -sed -n l
wyświetla czytelny widok znaków niedrukowalnych (i końca wiersza).Możesz to sprawdzić za pomocą prostej kontroli warunku bash:
Możesz połączyć test i naprawić w jednym kroku, testując
\r
(e) i usuwając je poprzez:Fix wykorzystuje Shell parametrów Expansion . Szczególna forma używana powyżej jest do wymiany podciągi oparte na proovided Wzór:
${parameter/pattern/string}
<- tylko pierwszy znalezionych Zastępuje wzór ze sznurkiem w zmiennej o nazwie * parametr. Aby zastąpić wszystkie wzorce, wystarczy zmienić pierwszy/
na//
.źródło
fix="....
linia?fix
może byćvar
sama - lub często możesz po prostu użyć rozszerzenia parametrów bez zmian, bez konieczności ponownego przypisywania (ewentualnie) zmodyfikowanej wartości.Możesz reprezentować
\r
jak$'\r'
w bash:Lub posiekaj ostatni
\r
wmyvar
:źródło
Co ciekawe, w wielu muszlach
getopts
jest bardzo prawdopodobnym kandydatem na taką pracę. Na początku może się to wydawać sprzeczne z intuicją, ale jeśli weźmiesz pod uwagę, żegetopts
„podstawową funkcją jest rozpoznawanie i oferowanie do interpretacji tylu określonych opcji wiersza poleceń, które można znaleźć w połączonej serii takich samych, to może zacząć robić trochę więcej rozsądku.Aby zademonstrować, z
bash
powłoki:W ten sposób czasami może być wygodne umożliwienie
getopts
obsługi demontażu jako rodzaju automatycznego pilota powłoki dla takich przypadków. Gdy to zrobisz, możesz po prostu odfiltrować niechciane bajty w / acase
lub[
przetestować]
i zbudować kopię zapasową ciągu od bajtu 1:Biorąc pod uwagę ten prosty przykładowy przypadek - i powłokę, która obsługuje rozszerzenia parametrów już wspomniane gdzie indziej - wspomniane rozszerzenia zapewnią ci lepszą obsługę. Ale pomyślałem,
getopts
że warto również wspomnieć, na wypadek gdybyś nie był świadomy jego możliwości w tym zakresie. Z pewnością, kiedy się o tym dowiedziałem, i tak znalazłem wiele przydatnych aplikacji.źródło
Podczas gdy Bash i inne języki powłoki są przydatne, czasem lepiej jest użyć prawdziwego języka skryptowego - takiego jak Perl. Perl może dość łatwo zastępować skrypty powłoki, które wywołują inne języki, takie jak sed i awk, a także polecenia UNIX. Nauczyłem się tego ponad 20 lat temu, pisząc skrypty C-Shell, które z kolei wywoływały sed, awk i różne komendy UNIX - przed wywołaniem kodu FORTRAN. W Perlu zrobiłbym:
źródło