Örneğin, verilen:
USCAGoleta9311734.5021-120.1287855805
Sadece şunu çıkarmak istiyorum:
US
Örneğin, verilen:
USCAGoleta9311734.5021-120.1287855805
Sadece şunu çıkarmak istiyorum:
US
Yanıtlar:
Muhtemelen en etkili yöntem, eğer bash
kabuğu kullanıyorsanız (ve yorumlarınıza göre öyle görünüyorsunuz), parametre genişletmenin alt dize varyantını kullanmaktır:
pax> long="USCAGol.blah.blah.blah"
pax> short="${long:0:2}" ; echo "${short}"
US
Bu, öğesinin short
ilk iki karakteri olacak şekilde ayarlanacaktır long
. Eğer long
iki karakterden kısa, short
buna aynı olacaktır.
Bu kabuk içi yöntem, işlem yaratma ek yükü olmadığından, bunu çok yapacaksanız genellikle daha iyidir (bahsettiğiniz rapor başına 50.000 kez). Harici programları kullanan tüm çözümler bu ek yükten zarar görecektir.
Ayrıca minimum bir uzunluk sağlamak istiyorsanız, elinizden önce aşağıdaki gibi bir şeyle doldurabilirsiniz:
pax> long="A"
pax> tmpstr="${long}.."
pax> short="${tmpstr:0:2}" ; echo "${short}"
A.
Bu, iki karakterden daha kısa olan herhangi bir şeyin sağ tarafa noktalarla (veya başka bir şey, yalnızca yaratırken kullanılan karakteri değiştirerek) doldurulmasını sağlayacaktır tmpstr
. Buna ihtiyacın olup olmadığı belli değil ama eksiksiz olması için onu koyacağımı düşündüm.
Bununla birlikte, bunu harici programlarla yapmanın birçok yolu vardır (örneğin, size ulaşamıyorsanız bash
), bunlardan bazıları:
short=$(echo "${long}" | cut -c1-2)
short=$(echo "${long}" | head -c2)
short=$(echo "${long}" | awk '{print substr ($0, 0, 2)}'
short=$(echo "${long}" | sed 's/^\(..\).*/\1/')
İlk ikisi ( cut
ve head
) tek satırlık bir dize için aynıdır - temelde ikisi de size yalnızca ilk iki karakteri geri verir. cut
Size her satırın head
ilk iki karakterini verecek ve size tüm girdinin ilk iki karakterini verecek olmaları bakımından farklılık gösterirler.
Üçüncüsü awk
, ilk iki karakteri çıkarmak için alt dize işlevini kullanır ve dördüncü , ilk iki karakteri yakalamak ve tüm satırı onlarla değiştirmek için sed
yakalama gruplarını ( ()
ve kullanarak \1
) kullanır . İkisi de birbirine benzer cut
- girdideki her satırın ilk iki karakterini sunarlar.
Girişinizin tek bir satır olduğundan eminseniz, bunların hiçbirinin önemi yoktur, hepsinin aynı etkisi vardır.
printf '%s'
yerine echo
: dizede garip karakter vardır durumunda stackoverflow.com/a/40423558/895245 : POSIX'deki için takıntılı head -c
POSIX değil, cut -c
ve awk substr
vardır sed \1
emin.
en kolay yol
${string:position:length}
Bu, $length
alt dizeyi, $string
adresinden çıkarır $position
.
Bu yerleşik bir bash olduğundan awk veya sed gerekli değildir.
Birkaç iyi yanıtlar ele verdik ve kendime yerleşik Bash ile gitmek istiyorum ama sorulduğunda beri sed
ve awk
ve ( neredeyse onlara göre) hiç kimse sunulan çözümler, sana bunları sunuyoruz:
echo "USCAGoleta9311734.5021-120.1287855805" | awk '{print substr($0,0,2)}'
ve
echo "USCAGoleta9311734.5021-120.1287855805" | sed 's/\(^..\).*/\1/'
awk
Biri oldukça açık olmalı, ama burada bir açıklamasını aşağıda sed
one:
substr($0,1,2)
.
İçindeyseniz şunu bash
söyleyebilirsiniz:
bash-3.2$ var=abcd
bash-3.2$ echo ${var:0:2}
ab
Bu tam da ihtiyacınız olan şey olabilir ...
Sadece grep:
echo 'abcdef' | grep -Po "^.." # ab
-P
seçeneği kaldırabilirsiniz . Tüm normal ifadeler bu kalıbı anlayacaktır.
Şunları kullanabilirsiniz printf
:
$ original='USCAGoleta9311734.5021-120.1287855805'
$ printf '%-.2s' "$original"
US
Gerçekten oldukça geç ama işte burada
sed 's/.//3g'
Veya
awk NF=1 FPAT=..
Veya
perl -pe '$_=unpack a2'
Kabuk komut dosyası kullanmak istiyorsanız ve posix olmayan uzantılara (sözde bashismler gibi) güvenmiyorsanız, grep, sed, cut, awk vb. Gibi harici araçların çatallanmasını gerektirmeyen teknikleri kullanabilirsiniz. betiğinizi daha az verimli hale getirin. Belki de verimlilik ve posix taşınabilirliği kullanım durumunuzda önemli değildir. Ancak böyle olması durumunda (veya sadece iyi bir alışkanlık olması durumunda), bir kabuk değişkeninin ilk iki karakterini çıkarmak için aşağıdaki parametre genişletme seçeneği yöntemini kullanabilirsiniz:
$ sh -c 'var=abcde; echo "${var%${var#??}}"'
ab
Bu , ilk iki karakteri (bu kısımdır) kaldırmak için "en küçük önek" parametre genişletmesini${var#??}
, ardından "en küçük son ek" parametre genişletmesini ( ${var%
parça) ilk iki karakter hariç tümü dizesini orijinalden kaldırmak için kullanır değer.
Bu yöntem daha önce "Shell = Değişken # ile başlayıp başlamadığını kontrol et" sorusuna verilen yanıtta açıklanmıştır . Bu cevap ayrıca, buradaki orijinal soru için geçerli olandan biraz farklı bir bağlamda kullanılabilecek birkaç benzer parametre genişletme yöntemini de açıklamaktadır.
Sisteminiz farklı bir kabuk kullanıyorsa (değil bash
), ancak sisteminizde varsa bash
, bir değişkenle bash
çağırarak doğal dize manipülasyonunu kullanmaya devam edebilirsiniz bash
:
strEcho='echo ${str:0:2}' # '${str:2}' if you want to skip the first two characters and keep the rest
bash -c "str=\"$strFull\";$strEcho;"
bash
zaten kullanmıyorsanız çağırır.
Sırf eğlence uğruna, fazla karmaşık ve yararsız olmalarına rağmen bunlardan bahsedilmediğini birkaçını ekleyeceğim:
head -c 2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
echo 'USCAGoleta9311734.5021-120.1287855805' | dd bs=2 count=1 status=none
sed -e 's/^\(.\{2\}\).*/\1/;' <( echo 'USCAGoleta9311734.5021-120.1287855805')
cut -c 1-2 <( echo 'USCAGoleta9311734.5021-120.1287855805')
python -c "print(r'USCAGoleta9311734.5021-120.1287855805'[0:2])"
ruby -e 'puts "USCAGoleta9311734.5021-120.1287855805"[0..1]'
dizgim = USCAGoleta9311734.5021-120.1287855805 ise
print substr(mystring,0,2)
ABD'yi yazdıracaktı
burada 0 başlangıç konumu ve 2 çok sayıda karakterin nasıl okunacağıdır
awk
. Üzgünüm, ilk başta anlayamadım.
Bu senin peşinde mi?
my $string = 'USCAGoleta9311734.5021-120.1287855805';
my $first_two_chars = substr $string, 0, 2;
ref: substr
perl -e 'print substr $ARGV[0], 0, 2' 'USCAGoleta9311734.5021-120.1287855805'