Yanıtlar:
Awk, sondaki beyaz boşlukla uğraşmak zorunda kalırsanız iyi bir seçenektir çünkü sizin için onu halleder:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Cut bununla ilgilenmez:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
Burada 'kes' hiçbir şey / boşluk yazdırmaz, çünkü bir boşluktan önceki ilk şey başka bir boşluktur.
-F","varsayılan alan ayırıcıyı (boşluk) virgülle geçersiz kılmak için kullanabilirsiniz .
harici komutlar kullanmaya gerek yok. Bash'in kendisi işi yapabilir. "Kelime1 kelime2" yi bir yerden aldığınızı ve bir değişkende depolandığınızı varsayarak, örn.
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
şimdi isterseniz başka bir değişkene $ 1 veya $ 2 vb. atayabilirsiniz.
stdin. @Matt M. , aynı şekilde aktarılıyor --demektir . argümanları içine boşluk-ayrılır , , , vb - sadece bir Bash programı değerlendirir bağımsız değişkenleri (örneğin, çek zaman gibi , vs.), bu yaklaşım bölmek için kabuk eğilimi yararlanır ihtiyacını ortadan kaldırarak, otomatik olarak bağımsız değişken olarak ya da . stdin$stringstdinstdin$1$2$3$1$2stdinawkcut
set, kabuk argümanlarını ayarlar.
word1=$(IFS=" " ; set -- $string ; echo $1)IFS'yi sözcükler arasındaki boşluğu doğru şekilde tanıyacak şekilde ayarlayın. 1 $ 'lık orijinal içeriğin bozulmasını önlemek için parantez içine alın.
string="*". Sürpriz.
Bence etkili bir yol bash dizilerinin kullanılması:
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
Ayrıca, bir boru hattındaki dizileri doğrudan okuyabilirsiniz:
echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*". Sürpriz.
whileHer satırdaki her ilk kelimeyi almak için sözdizimini kullanın . Aksi takdirde, Boontawee Home yaklaşımını kullanın. Ayrıca, echo "${array[0]}"gniourf-gniourf tarafından fark edildiği gibi genişlemeyi önlemek için alıntı yapıldığını lütfen unutmayın .
echo "word1 word2 word3" | { read first rest ; echo $first ; }
Bu, harici komutları kullanmama ve $ 1, $ 2, vb. Değişkenleri olduğu gibi bırakma avantajına sahiptir.
$1, $2, …olduğu gibi bırakmak, komut dosyası yazmak için son derece yararlı bir özelliktir!
Başta boşluk olmadığından eminseniz, bash parametresi değiştirmeyi kullanabilirsiniz:
$ string="word1 word2"
$ echo ${string/%\ */}
word1
Tek alandan kaçmaya dikkat edin. Daha fazla ikame modeli örneği için buraya bakın . Bash> 3.0'a sahipseniz, baştaki boşluklarla başa çıkmak için düzenli ifade eşleştirmesini de kullanabilirsiniz - buraya bakın :
$ string=" word1 word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
%% *İşte kabuk parametresi genişletmeyi kullanan başka bir çözüm . İlk kelimeden sonra birden fazla boşlukla ilgilenir. İlk kelimenin önündeki boşluklarla ilgilenmek, bir ek genişletme gerektirir.
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
%%Anlamına hangi silme olası en uzun maç *içinde (boşluk olursa olsun diğer karakterlerin herhangi numarası takip) sondaki parçası string.
Hız açısından en iyi yanıtlardan birkaçının nasıl ölçüldüğünü merak ettim. Aşağıdakileri test ettim:
1 @ mattbh's
echo "..." | awk '{print $1;}'
2 @ hayalet
string="..."; set -- $string; echo $1
3 @ boontawee-home
echo "..." | { read -a array ; echo ${array[0]} ; }
ve 4 @ boontawee-home
echo "..." | { read first _ ; echo $first ; }
Bunları, 5 harfli 215 kelimelik bir test dizesi kullanarak, macOS'ta bir Zsh terminalinde bir Bash komut dosyasında Python'un timeit ile ölçtüm. Her ölçümü beş kez yaptım (sonuçların tümü 100 döngü içindi, en iyisi 3) ve sonuçların ortalamasını aldı:
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")
İyi iş, seçmenler 👏 Oylar (bu yazı itibariyle) çözümün hızına uyuyor!
read -atire içinde geçersizdir), tire ile 3'ü ölçebilmeniz garip .
echo "word1 word2" | cut -f 1 -d " "
cut, "" (-d "") dizesi ile ayrılmış alanlar listesinden 1. alanı (-f 1) keser
read senin arkadaşın:
String bir değişkendeyse:
string="word1 word2"
read -r first _ <<< "$string"
printf '%s\n' "$first"Bir boru üzerinde çalışıyorsanız: ilk durum: yalnızca ilk satırın ilk kelimesini istersiniz:
printf '%s\n' "word1 word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
ikinci durum: her satırın ilk kelimesini istiyorsunuz:
printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; doneÖnde gelen boşluklar varsa bunlar işe yarar:
printf '%s\n' " word1 word2" | { read -r first _; printf '%s\n' "$first"; }
Perl, awk veya python içermeyen ve bunun yerine sed ile yapan gömülü bir cihazla çalışıyordum. İlk kelimeden önce ( cutve bashçözümlerinin ele almadığı) birden çok boşluğu destekler .
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
psSadece bash kullanan diğer çözümler pshizalamak için kullanılan ilk boşlukları kaldıramadığından, bu işlem kimlikleri için grep yaparken çok yararlıydı .