Karakterleri kabuk betiğinde bir dizenin belirli bir konumuna nasıl getirebilirim?


23

Karakterleri kabuk betiğinde bir dizenin belirli bir konumuna nasıl getirebilirim?

Yanıtlar:


37

"Parameter Expansion" ile bash'da $ {parametre: offset: length}

$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d

Düzenleme: Parametre genişletme olmadan (çok zarif değil, ama önce bana geldi)

$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r

1
gnu.org/software/bash/manual/… daha fazla ayrıntıya sahip
jsbillings


Ofseti 'uçtan' böyle de ayarlayabilirsinizecho ${var: -2:1}
Vassilis

Bu sözdizimi ksh93'ten gelir ve ayrıca zshve tarafından desteklenir mksh.
Stéphane Chazelas

6

Parametre genişletmeye alternatif expr substr

substr STRING POS LENGTH
    substring of STRING, POS counted from 1

Örneğin:

$ expr substr hello 2 1
e

serin, expr daha ayrıntılı kontrol etmeliydim.
forcefsck

1
Bu GNU coreutils expr ile çalışıyor gibi görünüyor olsa da substr, FreeBSD, NetBSD veya OS X expr dahil değildir. Bu taşınabilir bir çözüm değil.
ghoti

@ghoti, substrbunun aslında bir GNU uzantısı olmadığını unutmayın . Orijinal uygulaması expr70'lerin sonunda PWB Unix'ten geldi ve vardı substr(ama değil :).
Stéphane Chazelas

@ StéphaneChazelas, tarihsel bakış açısı eklediğiniz için teşekkür ederiz. :) PWB kullanımının OP ile ilgili olmadığından eminim, ancak özellikleri ve değişiklikleri on yıllar boyunca izlemek her zaman eğlencelidir. GNU, birçok insanın varsayılanı olma eğilimindedir, ancak genel olarak, açıkça POSIX olmayan ve büyük unice'den eksik olduğu bilinen seçenekleri kullanmaktan kaçınacağımı düşünüyorum .
ghoti

5

cut -c

Değişken yeni satır içermiyorsa şunları yapabilirsiniz:

myvar='abc'
printf '%s\n' "$myvar" | cut -c2

çıktılar:

b

awk substr değişkenin yeni satırları olsa bile çalışan başka bir POSIX alternatifidir:

myvar="$(printf 'a\nb\n')" # note that the last newline is stripped by
                           # the command substitution
awk -- 'BEGIN {print substr (ARGV[1], 3, 1)}' "$myvar"

çıktılar:

b

printf '%s\n'kaçış karakterleriyle ilgili sorunlardan kaçınmaktır: /programming//a/40423558/895245 eg:

myvar='\n'
printf '%s\n' "$myvar" | cut -c1

çıktılar \beklendiği gibi.

Ayrıca bakınız: /programming/1405611/extracting-first-two-characters-of-a-string-shell-scripting

Ubuntu 19.04'te test edildi.


printf '%s' "$myvar" | cut -c2yeni satır karakteri ile bitmediği printfsürece metin olmadığı için POSIX değildir $myvar. Aksi takdirde , girdinin her satırınıcut keserken değişkenin yeni satır karakteri içermediğini varsayar .
Stéphane Chazelas

Bu awkdaha verimli ve güvenilir olurduawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
Stéphane Chazelas

Mevcut GNU sürümlerinde cut, bunun çok baytlı karakterler için çalışmadığını unutmayın (mawk veya busybox awk için aynıdır)
Stéphane Chazelas

@ StéphaneChazelas puan için teşekkürler. İlkinde ne demek istediğini anlamadım: printf 'abc '| cut -c2bunun yanlış olduğu anlamına mı geliyor, çünkü hayır \n(bunu bilmiyorum) ya da myvar'ın yeni satırları varsa komutun başarısız olacağını mı düşünüyorsun?
Ciro Santilli 事件 改造 18 法轮功 六四 事件

1
cutGirdi metin değilse davranışı belirtilmez (ancak cutsatırları veya rasgele uzunluğu işlemek için uygulamalar gereklidir). Çıktısı printf abcdeğil metin bir satır karakteriyle bitmiyor olarak. Uygulamada uygulamaya bağlı olarak cut -c2, bunu yönlendirirseniz b, b<newline>ya hiç alırsınız ya da hiçbir şey almazsınız . printf 'abc\n' | cut -c2POSIX tarafından belirtilen bir davranışı almanız gerekir (çıktı için gereklidir b<newline>)
Stéphane Chazelas

1

İle zshya yash, kullanmak istiyorum:

$ text='€$*₭£'
$ printf '%s\n' "${text[3]}"
*

(içinde zshkısaltabilirsiniz printf '%s\n' $text[3]).


0

Cut komutunu kullanabilirsiniz. 3. pozisyonu almak için:

echo "SAMPLETEXT" | cut -c3

Bu bağlantıyı kontrol edin http://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html

( Gelişmiş durumlar ) IFS'de değişiklik yapmak, özellikle girdileriniz boşluklar olduğunda da iyi bir şeydir. Sadece bu durumda, aşağıdakini kullanın

saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs

IFSGönderdiğiniz kodda nasıl oyuna gireceğini göremiyorum .
Kusalananda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.