Ben yapıyorum find
ve sonra dosyaların bir listesini almak. Nasıl cat
(cat tüm bu dosyaların içeriğini görüntüler) gibi başka bir yardımcı programa nasıl boru ve temelde grep
bu dosyalardan bir şey gerekir .
Ben yapıyorum find
ve sonra dosyaların bir listesini almak. Nasıl cat
(cat tüm bu dosyaların içeriğini görüntüler) gibi başka bir yardımcı programa nasıl boru ve temelde grep
bu dosyalardan bir şey gerekir .
Yanıtlar:
Başka bir sürece borulama (Bu, yapmaya çalıştığınızı söylediklerinizi yerine getirmeyecek olsa da):
command1 | command2
Bu, command1 çıktısını command2 girişi olarak gönderir
-exec
üzerinde find
(bu, yapmak istediğiniz şeyi yapacak - ancak spesifik olan find
)
find . -name '*.foo' -exec cat {} \;
(Her şey arasında find
ve -exec
zaten kullandığınız bulmak yüklemleri vardır. {}
Eğer komuta içine bulundu belirli dosya (yerine yerleştirir cat {}
bu durumda); \;
bitmesini olan -exec
komutu.)
bir işlemin çıktısını başka bir işleme komut satırı bağımsız değişkenleri olarak gönderme
command2 `command1`
Örneğin:
cat `find . -name '*.foo' -print`
(Bu GERİ-KEŞİF benim klavyede tildeli ~ altında düzenli tırnak () olduğunu unutmayın.) Bu çıktısını gönderir command1
içine command2
komut satırı bağımsız değişkenleri olarak. Yine de boşluk içeren dosya adlarının (satırsonu vb.) Ayrı bağımsız değişkenlere bölüneceğini unutmayın.
find
yazmanıza izin verdiğini unutmayın : find . -name '*.foo' -exec cat {} +
Burada, tek bir komut çağrısında uygun sayıda dosya adını gruplaması gerektiğini +
belirtir find
. Bu oldukça kullanışlıdır (dosya adlarında boşluklar vb. İle başvurmadan ilgilenir -print0
ve xargs -0
).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
POSIX 2008, +
işaretleyiciyi ekledi; find
bu, artık makul olduğu kadar çok dosyayı tek bir komut yürütmesinde otomatik olarak gruplandırdığı anlamına geliyor, tıpkı xargs
bir çok avantajla:
Dosya adı sorunu ile ilgili bir sorun olduğunu xargs
olmadan -0
seçeneği ve konuya 'hatta sıfır dosya adları ile çalıştırmak' olan veya olmayan bir sorun olduğunu -0
seçenek - ama GNU xargs
vardır -r
ya --no-run-if-empty
onun için ona karşı seçeneğine. Ayrıca, bu gösterim, performans farkını ölçmeniz muhtemel değil, süreç sayısını azaltır. Bu nedenle, mantıklı olarak şunları yazabilirsiniz:
find . -exec grep something {} +
find . -print | xargs grep something
Linux üzerinde konum veya GNU varsa find
ve xargs
komutları, daha sonra kullanmak -print0
ile find
ve -0
ile xargs
boşluk ve diğer garip top karakter içeren tanıtıcı dosya adlarına.
find . -print0 | xargs -0 grep something
grep
Dosya adlarını (yalnızca metin) istemiyorsanız, uygun bir seçenek ekleyin grep
(genellikle -h
'başlıkları' bastırmak için). Kesinlikle dosya adı ile yazdırılır garanti etmek için grep
(sadece bir dosya bulunursa veya son çağırma bile grep
sadece 1 dosya adı verilir), sonra eklemek /dev/null
için xargs
daima en az iki dosya adları olacak böylece, komut satırından.
xargs grep something
.
find
standart girişine eklenir xargs
. xargs
Program boşluk en (boşluk, yeni satır sekme, vs) girişi bölme, standart okur ve komuta sözcük sayısını ekler grep something
ve komut hattı yürütür. xargs
daha sonra giriş okumaya ve giriş bitene kadar komutları yürütmeye devam eder. komutu verilen girdi için gerektiği sıklıkta xargs
çalıştırır grep
( find
bu örnekte).
/dev/null
Hata mesajlarını kaybetmek için stderr yönlendiriliyor .
Teknik olarak hepsi piping kullanmasa da find
, cat
komut tarafından döndürülen dosyaların listesini komuta iletmenin birkaç yolu vardır ve hiçbiri doğrudan doğrudan boru oluşturmaz cat
.
En basiti backticks ( `
) kullanmaktır :
cat `find [whatever]`
Bu, çıktısını alır find
ve etkin bir şekilde komut satırına yerleştirir cat
. find
Çok fazla çıktı (bir komut satırına sığabileceğinden daha fazla) veya çıktıda özel karakterler (boşluklar gibi) varsa bu işe yaramaz .
Aşağıdakiler de dahil olmak üzere bazı kabuklarda, ters çentikler yerine bash
kullanılabilir $()
:
cat $(find [whatever])
Bu daha az taşınabilir, ancak tartışılabilir. Bunun yanı sıra, geri tepmelerle hemen hemen aynı uyarılara sahiptir.
Bulunan şeyde başka komutlar çalıştırmak yaygın bir kullanım olduğundan find
, find, -exec
bulduğu her dosya için bir komut yürüten bir eyleme sahiptir:
find [whatever] -exec cat {} \;
{}
Dosya için bir yer tutucudur ve \;
komuta uç işaretleri (Mümkün sonra diğer işlemler olur -exec
.)
Bu, verimsiz olabilen ve bazı komutlar için istediğiniz davranışlara sahip olmayabilecek birden fazla dosya adını geçirmenin cat
tek bir örneğini çalıştırmak yerine her bir dosya için bir kez çalışır cat
(iyi olsa da cat
). Sözdizimi de yazmak için gariptir - noktalı virgülten kaçmanız gerekir çünkü noktalı virgül kabuğa özeldir!
Bazı sürümleri find
(özellikle GNU sürümü) ;
, +
aşağıdakilerin -exec
daha az örneğini çalıştırmak için 'ekleme' modunu kullanmanıza izin verir cat
:
find [whatever] -exec cat {} +
Bu, her çağrı için birden fazla dosya adı geçirecektir cat
, bu da daha verimli olabilir.
Ancak bunun tek bir çağrı kullanacağının garanti edilmediğini unutmayın . Komut satırı çok uzun olursa, argümanlar birden çok çağrısına yayılır cat
. İçin cat
bu muhtemelen büyük bir anlaşma değil, ama diğer bazı komutlar için bu istenmeyen şekilde davranışını değiştirebilir. Linux sistemlerinde, komut satırı uzunluk sınırı oldukça büyüktür, bu nedenle birden fazla çağrmaya bölünmek diğer bazı işletim sistemlerine kıyasla oldukça nadirdir.
Klasik / taşınabilir yaklaşım xargs
şunları kullanmaktır :
find [whatever] | xargs cat
xargs
belirtilen komutu çalıştırır ( cat
bu örnekte) ve stdin'den okuduklarına göre argümanlar ekler. Gibi sadece -exec
ile +
gerekirse bu komut satırı yukarı kıracak. Yani, find
çok fazla çıktı üretirse, cat
birden çok kez çalışır. Daha -exec
önceki bölümde bahsedildiği gibi, bu bölünmenin farklı davranışlara yol açabileceği bazı komutlar vardır. Bunun xargs
gibi xargs
kullanmanın, boşlukları sınırlayıcı olarak kullandığından dosya adlarındaki boşluklarla ilgili sorunları olduğunu unutmayın .
En sağlam, taşınabilir ve verimli yöntem ayrıca xargs
şunları kullanır :
find [whatever] -print0 | xargs -0 cat
-print0
Bayrak söyler find
kullanmak \0
dosya adları arasında (null karakteri) ayraçları ve -0
bayrak söyler xargs
bunlar beklemek \0
ayraçları. Bu, -exec
... +
yaklaşımla hemen hemen aynıdır , ancak daha taşınabilir (ama ne yazık ki daha ayrıntılı).
ls
.
$()
Ayrıca dışındaki komutlarla da çalışır find
.
Bana bir kabuk senaryosu için bir iş gibi geliyor:
for file in 'find -name *.xml'
do
grep 'hello' file
done
ya da böyle bir şey
Find komutu, bunun gibi şeyler için kullanabileceğiniz bir -exec argümanına sahiptir, bunu kullanarak doğrudan grep'i yapabilirsiniz.
Örneğin ( buradan, bu sayfadaki diğer iyi örnekler ):
find . -exec grep "www.athabasca" '{}' \; -print
Bash'da aşağıdakiler uygun olacaktır:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Bu, /dir
dizindeki tüm dosyaları bulur ve güvenli bir şekilde xargs
sürecek dosya adlarını güvenli bir şekilde aktarır grep
.
xargs
Binlerce dosyanız varsa atlamak iyi bir fikir değildir /dir
; cat
aşırı değişken listesi uzunluğu nedeniyle kırılacaktır. xargs
her şeyi sizin için halledecek.
-print0
Argüman find
ile mesh -0
argüman için xargs
düzgün boşluklu dosya isimlerinin işlenmesinde. To -i
argümanı xargs
, cat
komut satırında gereken yere dosya adını eklemenizi sağlar . Köşeli parantezlerin yerine cat
komuttan geçirilen dosya adı kullanılır find
.
Bu benim için çalışıyor
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Ggrep kullanın .
ggrep -H -R -I "mysearchstring" *
geçerli dizinde veya alt dizinde bulunan metin içeren unix'te bir dosyayı aramak için
Bu, yalnızca dosyaların adını ve içeriğini yinelemeli olarak yazdırır.
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Düzenle (Geliştirilmiş sürüm): Bu, yalnızca metin (ascii) dosyalarının adını ve içeriğini yinelemeli olarak yazdırır.
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Bir deneme daha
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Dosyalarda metin bulmaya mı çalışıyorsunuz? Bunun için grep'i kullanabilirsiniz ...
grep searchterm *
/ Ghi ve / jkl dizinlerindeki bir sunucudaki tüm abc.def dosyalarının içeriğini listelemek ve görmek için
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
Girişleri yorumlayan ve görüntüleyen abc.def dosyalarını listelemek için / ghi ve / jkl dizinlerindeki bu girişlere bakın.
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -print
benim için harika çalıştı ... Teşekkürler