Bash'daki bir karakterden sonra tüm metni nasıl kaldırabilirim?


147

Bir karakterden sonra tüm metni nasıl kaldırabilirim, bu durumda bash içinde iki nokta üst üste (":")? Kolonu da çıkarabilir miyim? Nasıl yapılacağı hakkında hiçbir fikrim yok.

Yanıtlar:


135

Bir örnek faydalı olabilir, ancak sizi doğru anladıysam, bu işe yarardı:

echo "Hello: world" | cut -f1 -d":"

Bu "merhaba: dünya" yı "merhaba" a dönüştürecektir.


5
cutama Dennis'in cevabı daha iyi ve daha esnek. Herkes yeni bir süreç ortaya çıkıp çıkmadığını biliyor mu cut?
JoBu1324

3
Bash'in yerleşik parametre genişletme özelliklerini kullanmak basenameve gibi alt kabukları çalıştırmaktan daha iyidir cut, Dennis'in aşağıdaki cevabına bakın
Louis Maddox

1
cutstdin'den okuyabilir, bu nedenle özellikle bir dosyanın içeriği gibi işlemeniz gereken çok uzun bir dizeniz olduğunda daha iyidir.
Sahas

1
Ve bu nasıl uygulanacaktı hello: world. Bu yarım cevap.
K - SO'da toksisite artıyor.

{Var /: / ''} gibi ikame sözdizimi kullanılarak da yapılabilir, ancak yalnızca bash'de çalışır ..
Mahesh

266

Bash'te (ve ksh, zsh, tire, vb.), %Dizenin sonundaki #karakterleri kaldıracak veya dizenin başındaki karakterleri kaldıracak parametre genişletmeyi kullanabilirsiniz . Bu karakterlerden tek birini kullanırsanız, eşleşen en küçük dize kaldırılır. Karakteri iki katına çıkarırsanız, en uzun karakter kaldırılır.

$ a='hello:world'
$ b=${a%:*}
$ echo "$b"
hello
$ a='hello:world:of:tomorrow'
$ echo "${a%:*}"
hello:world:of
$ echo "${a%%:*}"
hello
$ echo "${a#*:}"
world:of:tomorrow
$ echo "${a##*:}"
tomorrow

6
Bu yerel kabuk dizgisi manipülasyonudur, bu nedenle başka hiçbir işlem üretilmez. Referans Bash Parametreleri Değiştirme , Bash String Manipülasyonu ve Daha İyi Bash Scripting
Dodzi Dzakuma

@denniswilliamson ben gibi belirli bir dize sonra 2 karakter silindi nasıl olur hello:worldhale gelecektir hello:wokullanarak ${a%:*}?
3kstc

Harika cevap, çok teşekkürler, ama "${a##*:}"sadece almak için eklemek de güzel olacak tomorrow=)
avtomaton

1
@openCivilisation: Muhtemelen o zaman düzenli ifade eşleşmesi kullanmanız gerekir a='hello:world:of:tomorrow'; pattern=''^([^:]*:).*$':; [[$ a = ~ $ desen]]; echo "$ {BASH_REMATCH [1]}" `. Bu sadece bir kolon varsa eşleşir. Bunun isteğe bağlı olmasını istiyorsanız, farklı bir desen kullanılması gerekir. Bash normal ifadelerinin (ve genel olarak normal ifadelerin) açıklaması bu yorumların kapsamı dışındadır. Bu konuyu tartışan veya kendinize ait başka sorular bulabilirsiniz.
sonraki duyuruya kadar duraklatıldı.

1
@ kp123: Cevabımdaki ilk örnek. İkinci kez gösterdiğimde ("yarının" kaldırıldığı yer), neredeyse tam olarak sorduğunuz durum budur.
sonraki duyuruya kadar duraklatıldı.


4
egrep -o '^[^:]*:'

bunu nasıl yorumlayacağınızı açıklayabilir misiniz, teşekkürler.
rɑːdʒɑ

1
egrepile grep olduğunu -E. Burada normalden fark yok grep. -ogrep'e, satırın yalnızca ifadeyle eşleşen kısmını yazdırmasını söyler. ^eşleşmeyi satırın başına sabitler. [^:]*karakter olmayan sıfır veya daha fazla karakterle eşleşir :. :karakteri eşleştirir :.
cdhowie

Açıklama için tekrar teşekkürler
rɑːdʒɑ

3

Diyelim ki şu biçimde bir dosyaya sahip bir yolunuz var:

/dirA/dirB/dirC/filename.file

Şimdi sadece dört "/" içeren yolu istiyorsunuz. tip

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-4 -d"/"

ve çıktınız

/dirA/dirB/dirC

Cut kullanmanın avantajı, en üstteki dizinin yanı sıra dosyayı da kesebilmenizdir (bu örnekte);

$ echo "/dirA/dirB/dirC/filename.file" | cut -f1-3 -d"/"

Çıktınız

/dirA/dirB

Her şeyi dizenin diğer tarafından da yapabilseniz de, bu durumda yazmak çok mantıklı olmaz.

$ echo "/dirA/dirB/dirC/filename.file" | cut -f2-4 -d"/"

sonuç

dirA/dirB/dirC

Diğer bazı durumlarda, son dava da yardımcı olabilir. Son çıktının başında "/" olmadığını unutmayın.


2
"/Resources/views/admin/users/relationships/posts.blade.php" dizininiz varsa ve "/" ifadesinin LAST oluşumundan sonra her şeyi kısaltmak istiyorsanız, " "karakter dizgide. Bu yüzden burada çıktının "/ resources / views / admin / users / relation /" (ya da / resources / views / admin / users / Bunu nasıl yaptın?
kp123

-1

son ":" örneğinden sonra her şeyi kırp

cat fileListingPathsAndFiles.txt | grep -o '^.*:'

ve son ":"

cat file.txt | grep -o '^.*:' | sed 's/:$//'

@ kp123: Değiştirmek istediğimiz :ile /(sed kolon olması gereken yerde \/)

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.