N-te słowo w zmiennej łańcuchowej


85

W Bash chcę uzyskać n-te słowo ciągu trzymanego przez zmienną.

Na przykład:

STRING="one two three four"
N=3

Wynik:

"three"

Jakie polecenie / skrypt Bash może to zrobić?

Odpowiedzi:


95
echo $STRING | cut -d " " -f $N

3
cut zakończy się niepowodzeniem w przypadku żądania pola, które nie istnieje. Zamiast zwracać „”, zwróci sam łańcuch. Przykład: echo "aaaa" | wynik cut -f2 to „aaaa”, a nie pusty wynik o zerowej długości.
ajaaskel

@ajaaskel Wydaje się, że dzieje się tak, gdy w danych wejściowych nie znaleziono separatora . I to zachowanie można obecnie zmienić za pomocą opcji --only-delimited.
Samuli Pahaoja

64

Alternatywa

N=3
STRING="one two three four"

arr=($STRING)
echo ${arr[N-1]}

3
Używanie do tego celu tablic bash jest „najlepszym” rozwiązaniem. Nienawidzę używać awk lub sed, ponieważ nie widzę ich zainstalowanych we wszystkich konfiguracjach, zwłaszcza w msys.
Sundar

1
Mimo że echo „nie jest konieczne”, uznałem je za przydatne do zrozumienia, jak używać elementów arr. Dzięki
Chen Li Yong

1
Jeśli ustawiłeś IFS(wewnętrzny separator pól) na „:” lub coś innego zamiast odstępu, zmień to z powrotem, zanim spróbujesz.
Noumenon

1
To powinna być właściwa odpowiedź. Używanie tablic do tego celu jest proste i sprytne.
ajaaskel

31

Za pomocą awk

echo $STRING | awk -v N=$N '{print $N}'

Test

% N=3
% STRING="one two three four"
% echo $STRING | awk -v N=$N '{print $N}'
three

9

Plik zawierający wyciągi:

cat test.txt

Wynik:

This is the 1st Statement
This is the 2nd Statement
This is the 3rd Statement
This is the 4th Statement
This is the 5th Statement

Aby więc wydrukować czwarte słowo tego typu instrukcji:

cat test.txt |awk '{print $4}'

Wynik :

1st
2nd
3rd
4th
5th

2
OP mówi, że łańcuch jest w zmiennej, a nie w pliku.
codeforester

3

Bez drogich wideł, bez rur, bez bashizmów:

$ set -- $STRING
$ eval echo \${$N}
three

Ale uważaj na globbing.


2
STRING=(one two three four)
echo "${STRING[n]}"

2
W twoim przykładzie, czy STRING to naprawdę ciąg? Wygląda jak tablica.
Nicolas Raoul

@NicolasRaoul Tak, właściwie masz rację. Ale napisałem, aby być alternatywą dla.
mnrl
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.