Câu trả lời:
Awk là một lựa chọn tốt nếu bạn phải đối phó với khoảng trắng ở cuối bởi vì nó sẽ chăm sóc nó cho bạn:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Cut sẽ không quan tâm đến điều này mặc dù:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
'Cắt' ở đây in không có gì / khoảng trắng, bởi vì điều đầu tiên trước một không gian là một không gian khác.
-F","
để ghi đè dấu tách trường mặc định (dấu cách) bằng dấu phẩy.
không cần sử dụng các lệnh bên ngoài. Bash chính nó có thể làm công việc. Giả sử "word1 word2" bạn nhận được từ đâu đó và được lưu trữ trong một biến, ví dụ:
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
bây giờ bạn có thể gán $ 1, hoặc $ 2, vv cho một biến khác nếu bạn muốn.
stdin
. @Matt M. --
có nghĩa là stdin
, vì vậy $string
đang được thông qua như stdin
. stdin
là khoảng trắng tách thành đối số $1
, $2
, $3
, vv - giống như khi một Bash đánh giá lại chương trình đối số (ví dụ như kiểm tra $1
, $2
vv), phương pháp này có lợi thế của xu hướng của vỏ để phân chia các stdin
thành đối số tự động, loại bỏ sự cần thiết awk
hay cut
.
set
đặt đối số shell.
word1=$(IFS=" " ; set -- $string ; echo $1)
Đặt IFS để nhận dạng chính xác khoảng trắng giữa các từ. Gói trong ngoặc đơn để tránh ghi đè nội dung gốc của $ 1.
string="*"
. Sự ngạc nhiên.
Tôi nghĩ một cách hiệu quả là sử dụng mảng 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
Ngoài ra, bạn có thể đọc trực tiếp các mảng trong một đường ống:
echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*"
. Sự ngạc nhiên.
while
cú pháp để lấy từng từ đầu tiên ở mỗi dòng. Nếu không, sử dụng phương pháp Boontawee Home. Ngoài ra, xin lưu ý rằng echo "${array[0]}"
đã được trích dẫn để ngăn chặn sự mở rộng như được chú ý bởi gniourf-gniourf.
echo "word1 word2 word3" | { read first rest ; echo $first ; }
Điều này có lợi thế là không sử dụng các lệnh bên ngoài và giữ nguyên các biến $ 1, $ 2, v.v.
$1, $2, …
nguyên các biến là một tính năng cực kỳ hữu ích cho việc viết kịch bản!
Nếu bạn chắc chắn không có khoảng trắng hàng đầu, bạn có thể sử dụng thay thế tham số bash:
$ string="word1 word2"
$ echo ${string/%\ */}
word1
Xem ra cho thoát khỏi không gian duy nhất. Xem ở đây để biết thêm ví dụ về các mẫu thay thế. Nếu bạn có bash> 3.0, bạn cũng có thể sử dụng kết hợp biểu thức chính quy để đối phó với các khoảng trắng hàng đầu - xem tại đây :
$ string=" word1 word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
%% *
Đây là một giải pháp khác sử dụng mở rộng tham số shell . Nó chăm sóc nhiều không gian sau từ đầu tiên. Xử lý khoảng trắng ở phía trước của từ đầu tiên yêu cầu mở rộng thêm.
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
Dấu %%
hiệu xóa kết quả khớp dài nhất có thể của *
(một khoảng trắng theo sau bởi bất kỳ số lượng ký tự nào khác) trong phần dấu của string
.
Tôi tự hỏi làm thế nào một số câu trả lời hàng đầu đo lường về tốc độ. Tôi đã thử nghiệm như sau:
1 @ mattbh
echo "..." | awk '{print $1;}'
2 @ ghostdog74
string="..."; set -- $string; echo $1
3 @ boontawee-nhà
echo "..." | { read -a array ; echo ${array[0]} ; }
và 4 @ boontawee-home
echo "..." | { read first _ ; echo $first ; }
Tôi đã đo chúng bằng thời gian của Python trong tập lệnh Bash trong thiết bị đầu cuối Zsh trên macOS, sử dụng chuỗi thử nghiệm với 215 từ 5 chữ cái. Có phải mỗi lần đo năm lần (kết quả là tất cả cho 100 vòng, tốt nhất là 3) và tính trung bình cho kết quả:
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")
Công việc tốt, cử tri Các phiếu bầu (như bài viết này) phù hợp với tốc độ của các giải pháp!
read -a
không hợp lệ trong dấu gạch ngang).
echo "word1 word2" | cut -f 1 -d " "
cắt cắt trường thứ nhất (-f 1) từ danh sách các trường được phân tách bằng chuỗi "" (-d "")
read
là bạn của bạn:
Nếu chuỗi nằm trong một biến:
string="word1 word2"
read -r first _ <<< "$string"
printf '%s\n' "$first"
Nếu bạn đang làm việc trong một đường ống: trường hợp đầu tiên: bạn chỉ muốn từ đầu tiên của dòng đầu tiên:
printf '%s\n' "word1 word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
trường hợp thứ hai: bạn muốn từ đầu tiên của mỗi dòng:
printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; done
Những công việc này nếu có không gian hàng đầu:
printf '%s\n' " word1 word2" | { read -r first _; printf '%s\n' "$first"; }
Tôi đã làm việc với một thiết bị nhúng không có perl, awk hoặc python và đã làm điều đó với sed thay thế. Nó hỗ trợ nhiều khoảng trắng trước từ đầu tiên (mà các giải pháp cut
và bash
không xử lý).
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
Điều này rất hữu ích khi grepping ps
ID quá trình vì các giải pháp khác ở đây chỉ sử dụng bash không thể xóa các khoảng trắng đầu tiên ps
sử dụng để căn chỉnh.