N-те слово у рядковій змінній


85

У Bash я хочу отримати N-те слово рядка, яке утримується змінною.

Наприклад:

STRING="one two three four"
N=3

Результат:

"three"

Яка команда / сценарій Bash може це зробити?

Відповіді:


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

3
вирізати не вдасться при запиті поля, яке не існує. Замість повернення "" він поверне сам рядок. Приклад: echo "aaaa" | результат cut -f2 - це "aaaa", а не результат порожньої нульової довжини.
ajaaskel

@ajaaskel Це, здається, трапляється, коли роздільник не знаходиться у вхідних даних. І цю поведінку сьогодні можна змінити, використовуючи опцію --lyly-delimited.
Самулі Пахаоджа

64

Альтернатива

N=3
STRING="one two three four"

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

3
Використання масивів bash для цього є "найкращим" рішенням, я ненавиджу використовувати awk або sed, оскільки я не бачу їх встановлених у всіх установках, особливо в установці msys.
Сундар

1
Незважаючи на те, що луна "не потрібна", я знайшов це корисним для розуміння того, як використовувати елементи arr. Дякую
Чень Лі Йонг,

1
Якщо ви встановили IFS(внутрішній роздільник полів) значення ':' або щось інше, а не пробіли, змініть його назад, перш ніж спробувати це.
Noumenon,

1
Це повинна бути правильна відповідь. Використовувати для цієї мети масиви і просто, і розумно.
ajaaskel

31

Використовуючи awk

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

Тест

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

9

Файл, що містить деякі твердження:

cat test.txt

Результат:

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

Отже, щоб надрукувати 4-те слово цього виразу:

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

Вихід:

1st
2nd
3rd
4th
5th

2
OP каже, що рядок міститься у змінній, а не у файлі.
codeforester

3

Ні дорогих вилок, ні труб, ні башизмів:

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

Але остерігайтеся глобінгу.


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

2
У нашому прикладі STRING - це справді рядок? Це схоже на масив.
Ніколас Рауль,

@NicolasRaoul Так, насправді ти маєш рацію. Але я писав, щоб бути альтернативою.
mnrl
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.