Как получить первое слово вывода команды в bash? - PullRequest
101 голосов
/ 14 марта 2010

У меня есть команда, например: echo "word1 word2". Я хочу поставить трубу (|) и получить слово 1 из команды.

echo "word1 word2" | ....

Я не знаю, что ставить после трубы.

Ответы [ 12 ]

170 голосов
/ 14 марта 2010

Awk - хороший вариант, если вам приходится иметь дело с конечными пробелами, потому что он позаботится об этом за вас:

echo "   word1  word2 " | awk '{print $1;}' # Prints "word1"

Cut не позаботится об этом, хотя:

echo "  word1  word2 " | cut -f 1 -d " " # Prints nothing/whitespace

'cut' здесь ничего не печатает / пробел, потому что первым, перед пробелом, был другой пробел.

63 голосов
/ 14 марта 2010

нет необходимости использовать внешние команды. Сам Bash может сделать эту работу. Предполагая, что «слово1 слово2» вы откуда-то получили и сохранили в переменной, например,

$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2

теперь вы можете назначить $ 1 или $ 2 и т. Д. Другой переменной, если хотите.

28 голосов
/ 03 мая 2015

Я думаю, что одним из эффективных способов является использование массивов bash:

array=( $string ) # do not use quotes in order to allow word expansion
echo ${array[0]}  # You can retrieve any word. Index runs from 0 to length-1

Кроме того, вы можете напрямую читать массивы в конвейере:

echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
19 голосов
/ 20 мая 2014
echo "word1 word2 word3" | { read first rest ; echo $first ; }

Это имеет то преимущество, что не использует внешние команды и оставляет переменные $ 1, $ 2 и т. Д. Без изменений.

13 голосов
/ 13 ноября 2014

Если вы уверены, что нет начальных пробелов, вы можете использовать подстановку параметров bash:

$ string="word1  word2"
$ echo ${string/%\ */}
word1

Остерегайтесь выхода из единственного пробела. Смотрите здесь для большего количества примеров шаблонов замещения. Если у вас bash> 3.0, вы также можете использовать сопоставление регулярных выражений, чтобы справиться с начальными пробелами - смотрите здесь :

$ string="  word1   word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
11 голосов
/ 14 марта 2010

Вы можете попробовать awk

echo "word1 word2" | awk '{ print $1 }'

С помощью awk действительно легко выбрать любое слово, которое вам нравится ($ 1, $ 2, ...)

6 голосов
/ 10 декабря 2016

Использование расширения параметра оболочки %% *

Вот еще одно решение, использующее расширение параметра оболочки . Он заботится о нескольких пробелах после первого слова. Для обработки пробелов перед первым словом требуется одно дополнительное расширение.

string='word1    word2  '
echo ${string%% *}
word1

Объяснение

%% означает удаление самого длинного соответствия * (пробел, за которым следует любое количество любых других символов), начиная с правой стороны переменной string.

5 голосов
/ 14 марта 2010
echo "word1 word2" | cut -f 1 -d " "

cut вырезает 1-е поле (-f 1) из списка полей, ограниченных строкой "" (-d "")

4 голосов
/ 14 марта 2018

Мне было интересно, как несколько лучших ответов оцениваются по скорости. Я проверил следующее:

1 @ mattbh's

echo "..." | awk '{print $1;}'

2 @ ghostdog74's

string="..."; set -- $string; echo $1

3 @ boontawee-home's

echo "..." | { read -a array ; echo ${array[0]} ; }

и 4 @ boontawee-home's

echo "..." | { read first _ ; echo $first ; }

Я измерил их по времени Python в скрипте Bash на терминале Zsh в macOS, используя тестовую строку с 215 5-буквенными словами. Делали каждое измерение пять раз (результаты были все для 100 циклов, лучший из 3), и усредняли результаты:

method       time
--------------------------------
1. awk       9.2ms
2. set       11.6ms (1.26 * "1")
3. read -a   11.7ms (1.27 * "1")
4. read      13.6ms (1.48 * "1")

Отличная работа, избиратели ? Голоса (на момент написания статьи) соответствуют скорости решений!

3 голосов
/ 13 ноября 2014

read ваш друг:

  • Если строка находится в переменной:

    string="word1 word2"
    read -r first _ <<< "$string"
    printf '%s\n' "$first"
    
  • Если вы работаете в трубе: первый случай: вам нужно только первое слово первой строки:

    printf '%s\n' "word1 word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
    

    второй случай: вам нужно первое слово каждой строки:

    printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; done
    

Они работают, если есть начальные пробелы:

printf '%s\n' "   word1 word2" | { read -r first _; printf '%s\n' "$first"; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...