Mam polecenia, na przykład: echo "word1 word2"
. Chcę wstawić potok ( |
) i uzyskać słowo1 z polecenia.
echo "word1 word2" | ....
Nie wiem, co położyć za fajką.
Awk to dobra opcja, jeśli masz do czynienia z końcowymi białymi spacjami, ponieważ zajmie się tym za Ciebie:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Cut nie zajmie się tym jednak:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
„Wytnij” tutaj nie drukuje nic / białych znaków, ponieważ pierwszą rzeczą przed spacją była kolejna spacja.
-F","
do zastąpienia domyślnego separatora pól (spacji) przecinkiem.nie ma potrzeby używania poleceń zewnętrznych. Sam Bash może wykonać zadanie. Zakładając, że „słowo1 słowo2” skądś pobrałeś i zapisałeś w zmiennej np
teraz możesz przypisać $ 1 lub $ 2 itd. do innej zmiennej, jeśli chcesz.
źródło
stdin
. @Matt M.--
oznaczastdin
, że$string
jest przekazywany jakostdin
.stdin
jest oddzielone białymi znakami na argumenty$1
,$2
,$3
, itd. - tak jak wtedy, gdy bash wartościowanie programu argumenty (np czek$1
,$2
itd), to podejście wykorzystuje skłonność powłoki o podzialestdin
automatycznie do argumentów, usuwając potrzebęawk
lubcut
.set
ustawia argumenty powłoki.word1=$(IFS=" " ; set -- $string ; echo $1)
Ustaw IFS, aby poprawnie rozpoznawał odstępy między wyrazami. Zawiń w nawiasy, aby uniknąć wybicia oryginalnej zawartości 1 USD.string="*"
. Niespodzianka.Myślę, że skutecznym sposobem jest użycie tablic bash:
Możesz także bezpośrednio czytać tablice w rurociągu:
źródło
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*"
. Niespodzianka.while
składni, aby pobrać każde pierwsze słowo w każdym wierszu. W przeciwnym razie użyj podejścia Boontawee Home. Należy również pamiętać, żeecho "${array[0]}"
zostało zacytowane, aby zapobiec ekspansji, jak zauważył gniourf-gniourf.Ma to tę zaletę, że nie używa zewnętrznych poleceń i pozostawia zmienne $ 1, $ 2 itd. Nienaruszone.
źródło
$1, $2, …
nienaruszonych jest niezwykle przydatną funkcją przy pisaniu skryptów!Jeśli jesteś pewien, że nie ma spacji wiodących, możesz użyć podstawiania parametrów bash:
Uważaj na ucieczkę z pojedynczej przestrzeni. Zobacz tutaj, aby uzyskać więcej przykładów wzorców zastępowania. Jeśli masz bash> 3.0, możesz również użyć dopasowywania wyrażeń regularnych, aby poradzić sobie ze spacjami wiodącymi - zobacz tutaj :
źródło
Możesz spróbować awk
W awk bardzo łatwo jest wybrać dowolne słowo (1 $, 2 $, ...)
źródło
Korzystanie z rozszerzania parametrów powłoki
%% *
Oto inne rozwiązanie wykorzystujące rozszerzenie parametrów powłoki . Dba o wiele spacji po pierwszym słowie. Obsługa spacji przed pierwszym słowem wymaga jednego dodatkowego rozszerzenia.
Wyjaśnienie
W
%%
oznacza usuwanie najdłuższy mecz*
(spację dowolnej liczby dowolnych innych znaków) w tylnej częścistring
.źródło
Zastanawiałem się, jak kilka najpopularniejszych odpowiedzi wypada pod względem szybkości. Przetestowałem:
1 @ mattbh's
2 @ ghostdog74's
3 @ boontawee-home's
i 4 @ boontawee-home's
Zmierzyłem je za pomocą czasu Pythona w skrypcie Bash w terminalu Zsh na macOS, używając ciągu testowego z 215 5-literowymi słowami. Wykonałem każdy pomiar pięć razy (wszystkie wyniki obejmowały 100 pętli, najlepszy z 3) i uśredniono wyniki:
Dobra robota, wyborcy 👏 Głosy (w chwili pisania tego tekstu) odpowiadają szybkości rozwiązań!
źródło
read -a
jest nieprawidłowy w myślniku).cut wycina pierwsze pole (-f 1) z listy pól rozdzielonych ciągiem znaków "" (-d "")
źródło
read
jest twoim przyjacielem:Jeśli ciąg jest w zmiennej:
Jeśli pracujesz w potoku: pierwszy przypadek: chcesz tylko pierwszego słowa z pierwszego wiersza:
drugi przypadek: chcesz, aby pierwsze słowo w każdym wierszu:
Działają, jeśli istnieją spacje wiodące:
źródło
Ponieważ perl zawiera funkcjonalność awk, można to również rozwiązać za pomocą perla:
źródło
Pracowałem z urządzeniem wbudowanym, które nie miało ani Perla, awk, ani Pythona i zamiast tego zrobiłem to z sedem. Obsługuje wiele spacji przed pierwszym słowem (których rozwiązania
cut
ibash
nie obsłużyły).Było to bardzo przydatne podczas grepowania
ps
dla identyfikatorów procesów, ponieważ inne rozwiązania tutaj używające tylko basha nie były w stanie usunąć pierwszych spacjips
używanych do wyrównania.źródło