2011-05-02 30 views
5

Ben ls "$ değişkeni" şeklinde tüm dosyaları benim komut almaya çalışıyorum. *bash komut

parametre her zaman İstiyorum .001 uzantılı bir dosyadır

first="$1" 
others=${first%.001} 
ls $others"*" 

Benim sorunum file[success].mpg.001 ve ne ls beslenen alır file[success].mpg* olduğu adlı dosyadır örneğin aynı ada ancak farklı uzantılı $ file.002, file.003 vb örn .: tüm dosyaları bulmak Bu,için ls: cannot access file[success].mpg*: No such file or directory verir. 210 ihtiyaçlar görmek için: Her şeyi çalışıyorum

file\[success\].mpg* 

, gözüme yaptığım tek şey ls parametre $ 1 eser beslenen, ama ben değil dosyasını = $ 1 yaptıktan sonra $ dosyasını beslenen eğer. Yani, değişkeni bir parametreye nasıl değiştirebilirim?

cevap

6

. Ayrıca, * alıntı gerekmez:

#!/bin/bash 
first="$1" 
others=$(printf %q "${first%.001}") 
ls $others* 

printf %q (bash Erkeğin sayfasına ilişkin) kabuk girişi olarak kullanılabilecek bir biçimde dize yeniden biçimlendirir.
Yukarıdaki çözüm dosya adlarında beyaz boşluklarla çalışmaz: Bir yoruma ilişkin

düzenlemek.

#!/bin/bash 
first="$1" 
others="${first%.001}" 
ls -- "$others"* 
+0

teşekkür çok daha farklı bir şekilde kullanmalısınız tahmin! – geekmagii

+0

Size yardımcı olabildiğime sevindim. – bmk

+1

Bu, adlarda parantez içeren, ancak boşluk gibi diğer garip karakterler için olmayan dosyalarda çalışır. Örneğin, ./findfiles1 "test [success] .mpg.001" 'ı denedim ve iki dosya adı olarak bunu ayrıştırdı ve bulamadı: 'ls: \ [success \] .mpg *: Böyle bir dosya yok veya dizin '' ls: test \: Böyle bir dosya ya da dizin yok. –

1

Kullanım yerine ls bulmak: Sen dize yeniden biçimlendirmek için bash 'ın printf komutunu kullanabilirsiniz

$ ls weg.* 
ls: weg.*: No such file or directory 
$ find . -name weg.\* 
$ 
+1

(http [birden fazla nedenlerle]: // mywiki.wooledge.org/ParsingLs) – l0b0

+0

bulabilirsiniz. -name dosyası [başarı] .mpg * hiçbir şey bulamıyor. l0b0 cevabı dan – geekmagii

+1

ben sadece ls – geekmagii

2

Sen çok uzakta değiliz: (diğer bazı cevaplar önce de belirtildiği gibi) bu gibi durumlar için bu printf kullanmak ancak düzgün bütün değişkenleri alıntı daha iyidir. Benim ilk düzeltme aşağıdaki satırı 3 değişiyor:

ls -- "${others}".* 

Bu $others genişletmek ve globbing gerçekleşmesini sağlayacaktır. *'u tüm eşleşen dosya adlarının listesine genişletmek için sorumlulukları. Dosya adlarının listesi daha sonra ls'a gönderilir. , Böylece

file1.* 

: Böyle bir şey göreceksiniz Çoğu durumda ls gibi geliyor: Dosya olmadığında zaman, kabuk ls topak geçer

file1.001 file1.002 file1.003 ... 

Ama ve yıldız işareti göreceksiniz senin satırın, ls $others"*", göreceğim bir yıldız işareti ekliyor.

file1.* dosya adınız yoksa (tam yıldız işaretleriyle), ls başarısız olur.

first="$1" 
others=`basename -- "$first" .001` 
ls -- "${others}".* 

vb basename size o dizinleri kaldırabilirsiniz avantaj sağlar kullanma:

Başka bir seçenek basename kullanmaktırDiğerleri dosyaların listesi ile ne yaptığını bağlı olarak belirttiğimiz gibi

Ancak, find iyi olabilir.

DÜZENLEME: Çift tireli, tüm * nix değişkenlerinde çalışmaz, ancak başka bir bağımsız değişken yoksa, ls ve basename komutlarına bildirir. Değişkenlerinizi alıntılamak en iyi uygulama olabilir, ancak veri güvenilmezse onları bırakmanın basitliğini tercih ederim. Verilerinizi bilin ve uygun şekilde alıntı yapın.

+0

Değişkenleriniz düzgün bir şekilde alıntılanmamıştır; bu, dosya adlarında boşluk veya başka "özel" karakterler içeriyorsa sorunlara neden olur. Bunun yerine 'ls -" $ others "*' ve 'basename -" $ first "' yerine kullanın. – Philipp

+0

@Philipp - Yeterince adil, düzenlenmiş. –

5

Sen değil joker değişkeni alıntı olmalıdır: others bir tire ile başlıyorsa bu kod bile çalışması gerekir böylece

ls -- "$others"* 

çift çizgi seçenekleri için arama durur. ls komut değil yanlış çözümden çok daha sık olduğunu

Not. Sadece listeyi gerçekten yazdırmak istiyorsanız kullanın, ör. Uzun formatta:

ls -l -- "$others"* 

sadece isimleri yazdırmak isterseniz, hiç ls gerekmez:

echo "$others"* 

Maalesef echo ile -- kullanamazsınız. Ancak, dosya adlarının dizisini istiyorsanız kullanıyorum

filenames=("$others"*) 

kullanmak Ve üzerlerine yineleme istesin

for filename in "$others"*