Відповіді:
Awk - це хороший варіант, якщо вам доведеться мати справу з пробілом пробілів, оскільки він піклується про вас за вас:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Cut не потурбується про це, хоча:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
"cut" тут не надрукує нічого / пробіл, тому що перше, що було перед пробілом, було іншим пробілом.
-F","для заміни роздільника поля за замовчуванням (пробіл) комою.
не потрібно використовувати зовнішні команди. Сам Баш може виконати роботу. Якщо припустити, що "word1 word2" ви дісталися звідкись і зберігаєте в змінній, наприклад
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
тепер ви можете призначити $ 1, або $ 2 і т.д. для іншої змінної, якщо хочете.
stdin. @ Matt M. --означає stdin, так $stringпередається як stdin. stdinє розділений пробілами в аргументи $1, $2, $3і т.д. - так само , як коли Bash Програма оцінює аргументи (наприклад , перевірка $1, $2і т.д.), цей підхід має перевагу тенденції оболонки, щоб розколоти stdinавтоматично в аргументи, усуваючи необхідність awkабо cut.
setвстановлює аргументи оболонки.
word1=$(IFS=" " ; set -- $string ; echo $1)Встановіть IFS, щоб правильно розпізнати пробіл між словами. Загорніть у круглі дужки, щоб уникнути розкрадання оригінального вмісту в 1 долар.
string="*". Сюрприз.
Я думаю, що одним із ефективних способів є використання масивів 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
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*". Сюрприз.
whileсинтаксис для отримання кожного першого слова в кожному рядку. В іншому випадку використовуйте підхід Boontawee Home. Також зауважте, що echo "${array[0]}"це було цитовано для запобігання розширення, як зауважило gniourf-gniourf.
echo "word1 word2 word3" | { read first rest ; echo $first ; }
Ця перевага полягає в тому, що не використовуються зовнішні команди і залишає змінними $ 1, $ 2 і т.д. недоторканими.
$1, $2, …недоторканими - надзвичайно корисна функція для написання сценарію!
Якщо ви впевнені, що немає провідних пробілів, ви можете використовувати заміну параметрів bash:
$ string="word1 word2"
$ echo ${string/%\ */}
word1
Слідкуйте за тим, щоб уникнути єдиного простору. Тут див. Додаткові приклади моделей заміни. Якщо у вас bash> 3.0, ви також можете використовувати відповідність регулярних виразів, щоб впоратися з провідними пробілами - див. Тут :
$ string=" word1 word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
%% *Ось ще одне рішення, що використовує розширення параметрів оболонки . Він піклується про кілька пробілів після першого слова. Обробка пробілів перед першим словом вимагає додаткового розширення.
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
У %%Значить видалення максимально можливий матчу *(пробіл після чого будь-якої кількості будь-яких інших символів) в задній частині string.
Мені було цікаво, як кілька найвищих відповідей вимірюються за швидкістю. Я перевірив наступне:
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 ; }
Я вимірював їх timeit 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")
Хороша робота, виборці 👏 Голоси (на момент написання) відповідають швидкості рішення!
read -aнедійсне в тире).
echo "word1 word2" | cut -f 1 -d " "
cut вирізає 1-е поле (-f 1) зі списку полів, розділених рядком "" (-d "")
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"; }
Я працював із вбудованим пристроєм, який не мав ні perl, awk, ні python, і робив це замість sed. Він підтримує кілька пробілів перед першим словом (з яким cutі bashрішення не оброблялися).
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
Це було дуже корисно під час збирання psідентифікаторів процесів, оскільки інші рішення, що використовують лише bash, не змогли видалити перші пробіли, які psвикористовуються для вирівнювання.