GNU araçlarıyla:
find . -type f -exec grep -lZ FIND {} + | xargs -r0 grep -l ME
Standart olarak şunları yapabilirsiniz:
find . -type f -exec grep -q FIND {} \; -exec grep -l ME {} \;
Ancak bu, dosya başına iki greft çalıştırır. grepDosya adlarında herhangi bir karaktere izin verirken bu kadar çok s'yi çalıştırmayı ve yine de taşınabilir olmayı önlemek için şunları yapabilirsiniz:
convert_to_xargs() {
sed "s/[[:blank:]\"\']/\\\\&/g" | awk '
{
if (NR > 1) {
printf "%s", line
if (!index($0, "//")) printf "\\"
print ""
}
line = $0
}'
END { print line }'
}
find .//. -type f |
convert_to_xargs |
xargs grep -l FIND |
convert_to_xargs |
xargs grep -l ME
Çıkışı, tek, çift tırnak işaretleri ve ters eğik çizgilerin olabileceği ayrılmış bir kelime listesi olan findxargs (boş bir boşluk (SPC / TAB / NL ve yerel ayarınızdaki diğer boşluklar) ile ilgili bir biçime dönüştürmektir. xargsboşlukları ve birbirleri kaçış).
Genellikle find -print, dosya adlarını yeni satır karakteriyle ayırdığı ve dosya adlarında bulunan yeni satır karakterlerinden çıkmadığı için çıktısını sonradan işleyemezsiniz . Örneğin:
./a
./b
Bunun bbir dizinde adlandırılan bir dosya a<NL>.mı yoksa iki dosya ave mı olduğunu bilmenin bir yolu yok b.
Kullanarak .//., //başka bir şekilde çıktı olarak bir dosya yolunda görünemediğinden find(boş bir ada sahip bir dizin diye bir şey /olmadığı ve dosya adında izin verilmediği için), içeren bir satır görürsek //, yeni bir dosya adının ilk satırı. Bu awkkomutu, bu satırlardan önce gelen tüm yeni satır karakterlerinden kaçmak için kullanabiliriz .
Yukarıdaki örneği alırsak find, ilk durumda çıktı alır (bir dosya):
.//a
./b
Hangi awk kaçar:
.//a\
./b
Bu xargsonu tek bir argüman olarak görüyor. Ve ikinci durumda (iki dosya):
.//a
.//b
Hangi awkolduğu gibi xargsbırakılır , böylece iki argüman görür.