Подтвердить что ты не робот

Как получить первое слово вывода команды в bash?

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

echo "word1 word2" | ....

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

Я думаю, что одним из эффективных способов является использование массивов 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

Ответ 4

echo "word1 word2 word3" | { read first rest ; echo $first ; }

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

Ответ 5

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

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

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

$ string="  word1   word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1

Ответ 6

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

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

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

Ответ 7

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

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

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

объяснение

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

Ответ 8

echo "word1 word2" | cut -f 1 -d " "

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

Ответ 9

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

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 timeit в скрипте 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")

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

Ответ 10

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"; }

Ответ 11

Поскольку perl включает функции awk, это также можно решить с помощью perl:

echo " word1 word2" | perl -lane 'print $F[0]'

Ответ 12

Я работал со встроенным устройством, в котором не было ни perl, awk, ни python, а делал это с помощью sed. Он поддерживает несколько пробелов перед первым словом (которые не обрабатывались решениями cut и bash).

VARIABLE="  first_word_with_spaces_before_and_after  another_word  "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'

Это было очень полезно при подборе ps для идентификаторов процессов, поскольку другие решения, использующие только bash, не смогли удалить первые пробелы, которые ps использует для выравнивания.