Sed kullanarak dizeden ilk X karakterini nasıl çıkarabilirim?


126

Küçük bir endüstriyel kutuya gömülü Linux için kabuk komut dosyası yazıyorum. Metni içeren bir değişkenim var pid: 1234ve satırdan ilk X karakterini çıkarmak istiyorum, bu yüzden sadece 1234 kalıyor. "Temizlemem" gereken daha fazla değişken var, bu yüzden X ilk karakterleri kesmem gerekiyor ve ${string:5}sistemimde herhangi bir nedenle çalışmıyor.

Kutunun sahip olduğu tek şey sed.

Aşağıdakileri çalıştırmaya çalışıyorum:

result=$(echo "$pid" | sed 's/^.\{4\}//g')

Herhangi bir fikir?


10
Eğer ${string:5}siz Bash veya başka kabuk destekleri olduğunu sözdizimi olduğunu kullanmadığınız sonra çalışmaz. Hangi kabuğu ve sürümü kullanıyorsunuz? Senin işin neye benziyor? Benim tahminim sh(gibi dash) veya muhtemelen kullanıyorsun zsh.
sonraki duyuruya kadar duraklatıldı.

Yanıtlar:


-1

Bu da işi yapacak:

echo "$pid"|awk '{print $2}'

27
Bu soru, "dizedeki ilk N karakteri atla" için ilk isabettir. Soruyu cevaplamadın
jww

Bu işe yaramıyor gibi görünüyor ve işe
Alexander Mills

Benim sistemimde çalışıyor. Alan ayırıcınızda bir sorun olabilir, deneyin awk -F": " '{print $2}'. Yine de en sevdiğim çözüm değil.
mzuther

197

Aşağıdakiler çalışmalıdır:

var="pid: 1234"
var=${var:5}

bashKabuğun betiğinizi çalıştırdığından emin misiniz ?

POSIX uyumlu bile

var=${var#?????}

harici bir işlemin kullanılması tercih edilir, ancak bu, 5'i sabit uzunlukta bir model biçiminde sabit kodlamanızı gerektirir.


1
Uzunluğu ikinci bir parametre ile de belirtebilirsiniz: ${var:5:2}başlangıçta başlayacak 1ve dönecektir 12.
Max Candocia

109

İşte ilk X karakterlerini kullanarak kesmek için kısa bir yöntem cut(1). Bu örnek, 5. karakterden başlayan bir alt dizeyi keserek ilk 4 karakteri kaldırır.

echo "$pid" | cut -c 5-

2
Bu en basit çözüm!
Brandon

2
Teknik olarak OP sed'i istedi, ancak bunun "[bir terminalde / bash içinde] dizeden ilk X karakterini nasıl çıkarabilirim" için en iyi çözüm olduğunu düşünüyorum. Git ile birlikte kullanıldığında güzel:git log --pretty=oneline | cut -c 42- | head
marksiemers

1
+1 Basit ve faydalı çözüm .. URL'yi http: // <example.com> olarak aldığımda ve 'http: //' protokolünü kestiğimde 7 yerine 8 karakter söylemem gerekiyor. Bilmiyorum ama benim için böyle çalıştı.
Santosh Kumar Arjunan

1
Santosh Kumar Arjunan: Bunun nedeni "echo" $ pid "| cut -c 4-" örneğinin aslında ilk 4 karakteri kesmemesi, ancak 4. karakterden başlayarak alt dizeyi çıkarmasıdır. Bu nedenle aslında ilk 3 karakteri keser. Bu nedenle, ilk 7 karakteri kesmek istiyorsanız, 8. karakterden her şeyi çıkarmak istersiniz ve bu nedenle gerçekten "cut -c 8-"
al-ash

1
@DeanHiller cut -c ${LEN}-. Küme parantezleri, değişkenin ne olduğunu ve neyin olmadığını ayırt etmek için dizeyi geçerli değişken karakterlerle birleştirmek için kullanılır. Bununla ilgili daha fazla bilgi istiyorsanız, bunun neden / nasıl çalıştığı hakkında daha fazla kaynak için "bash değişkeni dizesi birleştirme" ye bakın.
JustCarty

46

Sözdizimini kullanmak için -rseçeneği ("kodda genişletilmiş normal ifadeler kullan") kullanın:sed{n}

$ echo 'pid: 1234'| sed -r 's/^.{5}//'
1234

1
Bir dizeden son X karakterini çıkarmak istersem durum nasıl olur?
Kokesh

5
@Kokesh: sed -r 's/.{5}$//'Bunun yerine son 5 karakteri
çıkarabilirsin

7
Ayraçlardan kaçarsanız -r( -EOS X, IIRC'de) olmadan da yapabilirsiniz ( bunun OS X'de çalışıp çalışmadığını bilmiyorum).
sonraki duyuruya kadar duraklatıldı.

2
@Dennis: Az önce kontrol ettim - parantezlerden kaçmak (ve bırakmak -r/ -E) OS X'te çalışıyor.
Gordon Davisson

16

Dizeden ilk iki karakteri kesin:

$ string="1234567890"; echo "${string:2}"
34567890

@ dtp70 Çok teşekkürler genel bir cevap, harika çalıştı!
wolfram77

10

böylece borunun o awk '{print substr($0,42)}'burada 42 damla karakter sayısı birden fazladır. Örneğin:

$ echo abcde| awk '{print substr($0,2)}'
bcde
$

8

Muhtemelen siz de olacaksınız cut. Öyleyse:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234

1
Sorun cut, boşluk dizilerini mantıklı bir şekilde işlememesi, boşlukları tr -s ' '"sıkıştırmak" için kullanmak , daha iyi davranmasını sağlar.
Thor

1
Tümüyle şarkı söyleyen bir dans aracı olması amaçlanmamıştır; basittir ve kutuda yazdığı gibi yapar ve yaygın olarak bulunur. Söz konusu gereksinimler için gayet iyi çalışması gerekir ve belirli konumlardan sabit karakterleri çıkarmaktan kesinlikle daha sağlamdır.
Shawn Çene

5

İşte ile çözümler olmuştur sed, awk, cutve kullanan bashsözdizimi. Sadece başka bir POSIX uyumlu varyantı eklemek istiyorum:

$ echo "pid: 1234" | tail -c +6
1234

-ckuyruğa, giriş verilerinin sonundan sayarak hangi bayt ofsetinin başlayacağını söyler, ancak sayı bir +işaretle başlıyorsa, giriş verilerinin başından sonuna kadardır.


4

cutBunun yerine kullanmak başka bir yol sed.

result=`echo $pid | cut -c 5-`

İlk 4 karakteri silmek istiyor. Bu ilk 4 karakteri alır.
MM.

2

Cevabı bu sorunun sağladığı saf sed'de buldum (kuşkusuz, bu soru gönderildikten sonra yayınlanmıştır). Bu tam olarak istediğiniz şeyi yapar, yalnızca sed'de:

result=\`echo "$pid" | sed '/./ { s/pid:\ //g; }'\``

Nokta sed '/./) eşleştirmek istediğiniz şeydir. Sorunuz tam olarak yapmaya çalıştığım şeydi, ancak benim durumumda bir dosyadaki belirli bir satırı eşleştirmek ve ardından yorumunu kaldırmak istedim. Benim durumumda:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/ { s/#\ //g; }' /path/to/target/file

-iSonra seddüzenlemek için yerinde dosya (eğer öncesinde dosyasını düzenleyerek için eşleşme ifadesi test etmek istiyorsanız bu anahtarı kaldırın).

(Bunu gönderdim çünkü bu soru sorulduğunda bunu tamamen sed ile yapmak istedim ve önceki cevapların hiçbiri bu sorunu çözmedi.)


1

Başlangıçtan itibaren n karakteri kaldırmak yerine, belki rakamları doğrudan çıkarabilirsiniz. Böyle ...

$ echo "pid: 1234" | grep -Po "\d+"

Bu daha sağlam bir çözüm olabilir ve daha sezgisel görünüyor.

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.