Przeczytałem kilka innych pytań dotyczących manipulacji ciągami bashowymi, ale wydaje się, że są to wyspecjalizowane aplikacje.
Zasadniczo, czy jest sposób, aby zrobić poniższe prostsze?
zamiast
$ string='hello world'; string2="${string// /_}"; echo "${string2^^}"
HELLO_WORLD
coś jak
$ echo 'hello world' | $"{-// /_}" | "${ -^^}"
HELLO_WORLD
Edytuj Jestem zainteresowany utrzymywaniem manipulacji bash, jeśli to możliwe, aby utrzymać prędkość (w przeciwieństwie do sed / awk, które mają tendencję do znacznego spowalniania moich skryptów)
Edycja2: @jimmij
Podoba mi się drugi przykład i doprowadziłem mnie do stworzenia funkcji.
bash_m() { { read x; echo "${x// /_}"; } | { read x; echo "${x^^}"; }; }
echo hello world | bash_m
HELLO_WORLD
tr
instrukcji, to odwrotnie, ponieważ czas odradzania procesów jest pomijalny w porównaniu do czasu manipulacji łańcuchem, dla któregosed
iawk
są oddani. Jeśli ciąg znaków jest bardzo długi, powiedzmy całą instrukcję bash, wtedy bash może po prostu odmówić kontynuowania, z powodu pewnych wewnętrznych ograniczeń.sed
,awk
,tr
lub podobnych. Spójrz na odpowiedź gena2x, którą edytowałem jakiś czas temu, dodając dokładnie tę informację: unix.stackexchange.com/questions/162221/ ... możesz porównać ją z odpowiedzią Terdona na to samo pytanie, w którym daje on czas na krótkie łańcuchy, w których spawnowanie procesu zajmuje najwięcej czasu. Możesz to przetestować samodzielnie i opublikować wynik.read x; echo $x
jest lepszy dla wydajności? Składnia nie wygląda na krótszą ani bardziej przejrzystą.x=${x// /_}; x=${x^^}
jest o wiele bardziej zwięzłym sposobem robienia tego samego{read x; echo ${x...
. Jeśli chodzi o wydajność, @jimmij wskazał, żetr
/sed
będzie szybszy niżbash
, przy równej liczbie rozwidleń. Użycie rury zawsze powoduje dodatkowy proces, więc argument o zapisaniu widelca nie ma już zastosowania. Tak więc, jeśli używasz potoków, po prostu użyjsed
/tr
itd. Jeśli możesz to zrobić w bash, zrób to i pomiń tenread x; echo $x
nonsens.Odpowiedzi:
Co powiedział Jimmij. Jego ostatnim przykładem jest najbliżej tego, co próbujesz wyrazić mimochodem.
Oto wariant tego tematu:
Byłbym skłonny do użycia
tr
, ponieważ jest dość szybki.Przypuszczam, że szkoda, że bash nie pozwala na zagnieżdżanie parametrów; OTOH, użycie takich zagnieżdżonych wyrażeń może z łatwością prowadzić do kodu, który jest bolesny do odczytania. Jeśli naprawdę nie potrzebujesz rzeczy, aby działać tak szybko, jak to możliwe, lepiej napisać kod, który jest łatwy do odczytania, zrozumienia i utrzymania, niż sprytnie wyglądający kod, który jest PITA do debugowania. A jeśli naprawdę robić rzeczy muszą być wykonywane z maksymalną prędkością należy używać skompilowany kod, nie skrypt.
źródło
Nie można w ten sposób przekazywać rozszerzeń parametrów. Kiedy mówisz o
x
używaniu$
symbolu w"${x}"
formie, to musi to być prawdziwa nazwa zmiennej, a nie standardowe wejście, przynajmniej nie wbash
. Wzsh
można wykonać zagnieżdżone podstawienia parametrów w następujący sposób:(uwaga:
:u
jest dlazsh
tego samego co^^
dlabash
)Zagnieżdżanie w bashu nie jest możliwe i myślę, że to, co napisałeś, jest najlepsze, co możesz dostać, ale jeśli z jakiegoś dziwnego powodu musisz włączyć rury do równania, możesz spróbować tego:
źródło
tr
/sed
są szybsze niżbash
podczas przetwarzania ciągów, i biorąc pod uwagę, w jaki sposób używasz potoków do przekazywania ciągów przez standardowe we / wy, widzę dosłownie zero punktu, aby wykonywać te operacje w bashu w przeciwieństwie dotr
/sed
. Dlaczego ktoś miałby| { read x; echo $x... }
w przeciwieństwie do| sed
czegoś, co robi to samo?echo
iread
są bash Zabudowy, więc w zasadzie trochę szybciej). Jak już napisałem w odpowiedzi, progresywne manipulowanie parametrami, jakie OP ma w pytaniu, jest najlepsze, co moim zdaniem można uzyskać do tego zadania w bash. W każdym razie problem jest raczej akademicki.