find: -exec için argüman eksik


18

Aşağıdaki komutu çalıştırmaya çalışıyorum:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +

Bu bir hata döndürüyor:

find: missing argument to -exec

Man sayfasıyla eşleştiği gibi, bu komutta neyin yanlış olduğunu göremiyorum:

-exec komutu {} +

-Exec seçeneğinin bu değişkeni, seçilen dosyalarda belirtilen komutu çalıştırır, ancak komut satırı, seçilen her dosya adı sonuna eklenerek oluşturulur; komutun toplam çağrı sayısı, eşleşen dosya sayısından çok daha az olacaktır. Komut satırı, xargs'ın komut satırlarını oluşturduğu gibi oluşturulur. Komutta yalnızca bir {{} örneğine izin verilir. Komut başlangıç ​​dizininde yürütülür.

Ayrıca denedim:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+

+Sonunda kaçmayı denedin mi? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
jayhendren

3
GNU'nun eski bir sürümünü kullanıyor olabilirsiniz find. -exec cmd {} +Varyant POSIX olmasına ve 80'lerden beri mevcut olmasına rağmen , GNU bulguyu sadece (nispeten) yakın zamanda ekledi (2005). find --versionSize ne anlatıyor?
Stéphane Chazelas

2
@Koveras, o zaman bu olurdu. -exec {} +Daha eski GNU bulgularında, -print0 | xargs -r0benzer bir şey elde etmek için (POSIX dışı) kullanabilirsiniz. 4.11994 dan
Stéphane Chazelas

1
JRFerguson ki (silinmiş bir cevap olarak) işaret -namedesen argümanlar alıntı edilmelidir: -name "*.c" -o -name "*.h". -execHatayla ilgisi olmasa da bu doğrudur . Diğer tüm cevapların joker karakterleri tırnak içine aldığını fark edeceksiniz, ancak sadece Gilles bundan bahsediyor. ... (devamı)
G-Man 'eski durumuna Monica' Diyor

1
(Devamı)… jlliagre'nin cevabı isim ifadesini -name "*.[ch]"açıklama yapmadan daraltır . Bu, komut satırını basitleştirmenin ve özellikle  -o. İçeren ifadeleri -odoğru bulmak zordur. Seninki yanlış; Komutunuz hata vermeyecek şekilde sabitlenmişse (Gilles'in cevabında olduğu gibi), grepyalnızca .hdosyalarda çalışır. Yapmanız gerek '(' -name '*.c' -o -name '*.h' ')'.
G-Man 'eski durumuna Monica' Diyor

Yanıtlar:


18

Etrafta kullandığınız tek tırnakları kaldırmanız gerekir {}. Komut şu şekilde basitleştirilebilir:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +

Arkaik bir GNU bulma sürümü kullanırsanız, bu yine de çalışmalıdır:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;

Maalesef, backticks değil, tırnaklardı.
David Kennedy

{}Kabuklar için belirli bir anlamı olmadığı için alıntılar işe yaramaz .
jlliagre

Bulma man sayfalarından: '{}' dizesi, yalnızca find sürümlerinde olduğu gibi, yalnızca yalnız olduğu argümanlarda değil, komutun bağımsız değişkenlerinde gerçekleşen her yerde işlenen geçerli dosya adıyla değiştirilir. yapıların, kabuk tarafından genişletilmelerini önlemek için kaçmaları ('\' ile) veya alıntı yapılması gerekebilir. "
David Kennedy

1
Gerçekten de manuel sayfada okudum ama gerçek şu ki, kıvırcık parantezleri alıntılamayı gerektiren bir kabuk yok. Hangi kabuğu kullanıyorsun?
jlliagre

bash. Tırnaklar olsun ya da olmasın hatayı yine de alıyorum.
David Kennedy

10

“İçin argüman eksik -exec”, genellikle - argümanının execsonlandırıcısını kaçırdığı anlamına gelir . Sonlandırıcı ya yalnızca karakteri içeren bir argüman ;(kabuk komutunda alıntılanması gereken, bu yüzden genellikle yazılır \;ya da ';') ya da {}ve içeren iki ardışık argüman olmalıdır +.

Stephane Chazelas, GNU bulmanın -exec … {} +yalnızca desteklemeyen eski bir sürümünü kullandığınızı belirledi-exec {} \; . GNU'nun geç bir kullanıcısı olmasına rağmen -exec … {} +, daha az antika bir araç paketi ( git ve çok daha fazlasını içeren Cygwin gibi) veya gitten yoksun ama kötü çalışan-denemeye sahip olmayan GNUwin32 almanızı öneririm Cygwin'in verdiği linux-but-we-impose-windows vibe kullanımı). Bu özellik 9 yıl önce 4.2.12 sürümünde eklenmiştir (GNU findPOSIX uyumlu hale getirmek için en son tanımlanan özelliktir ).

Daha eski bir GNU bulgusuna bağlı kalmak isterseniz, benzer bir işlevsellik elde etmek için -print0ile birlikte kullanabilirsiniz xargs -0: gruplandırılmış komut yürütme, rasgele dosya adlarını destekleme.

find a/folder b/folder -name '*.c' -o -name '*.h' -print0 | xargs -0 grep -I foobar /dev/null

Her zaman findkomut satırındaki joker karakterleri alıntılayın . Aksi takdirde, bu komutu .cdosya içeren bir dizinden çalıştırırsanız , sıralanmamış geçerli dizindeki dosya *.clistesine genişletilir .c.

Ekleme /dev/nulliçin grepkomut satırında bile, her zaman dosya adını yazdırır o grep sağlamak için bir hile findtek eşleşme bulmak olur. GNU find ile başka bir yöntem seçeneği geçmektir -H.


1
Cygwin'in verdiği kötü-çalışan-kullanmaya-linux-ama-biz-empoze-eden pencere havası ile ne demek istiyorsun?
David Kennedy

GNUwin32 beklemiyor :(
David Kennedy

Soru hakkındaki yorumlarıma bakın.
G-Man, '

Yarıdaki alıntılar bir package.json betiğinin içinden çalıştı.
bvj

2

Gibi bir komut varsa

find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +

hata döndürür

find: missing argument to -exec

olası neden, findsözdizimini desteklemeyen çok eski GNU'dur -exec mycommand {} +. Bu durumda, birden fazla hedef toplamak ve sadece bir kez çalıştırmak yerine, bulunan her hedef -exec mycommand {} \;için bir mycommandkez çalışacak düşük performanslı yedek çalıştırmaktır mycommand.

Ancak, GNU findörn.

find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +

çünkü GNU , daha genel değil, findyalnızca gerçek birleşimi destekler . Diş telleri ile karakter arasında hiçbir şey olamaz . Bunu denerseniz, aynı hatayı alırsınız:{} +{} additional parameters ++

find: missing argument to -exec

Çözüm {} additional parameters \;işe yarayan ancak bulunan her hedef için komutu bir kez çalıştıracak sözdizimini kullanmaktır . GNU ile daha fazla performansa ihtiyacınız varsa find, verilen argümanlara ek parametreler ekleyebilen bir sarıcı komut dosyası yazmanız gerekir. Gibi bir şey

#!/bin/bash
exec mycommand "$@" additional parameters

yeterince iyi olmalı. Veya, geçici dosya oluşturmak istemiyorsanız, aşağıdaki gibi parametrelerin sırasını değiştirmek için tek astar kullanabilirsiniz:

find . -type f -and -name "*.ttf" -exec bash -c 'mycommand "$@" extra arguments' {} +

hangi yürütmek mycommand {list of ttf files} extra arguments. -cBayraktan sonra bash için özel karakterlerden iki kez kaçmanız gerekebileceğini unutmayın .


(1) Yukarıdakilerin soruyu gerçekten cevaplayan kısmı zaten diğer insanlar tarafından verildi. (2) Açıkladığınız şey GNU'daki bir kusur veya eksiklik finddeğil, POSIX tarafından belirtilen doğru davranıştır .
G-Man, '

1
+1 Son olarak, ek parametrelerin neden çalışmadığını yanıtlayan biri! POSIX tanımında bir eksiklik gibi görünüyor.
Jonathan

GNU'nuz findvarsa muhtemelen GNU'nuz vardır cp. Bu durumda , yürütme dizesinin sonundaki find ... -exec cp --target-directory ~/.fonts {} +tutabilirsiniz {}.
roaima

1

find . -type f -perm 0777 -exec chmod 644 {}\;

hata var find: missing argument to ``-exec'.

Arasına boşluk eklemek {}ve \düzeltmek:

find . -type f -perm 0777 -print -exec chmod 644 {} \;


1
findEldeki soruda komutta böyle bir sorun yok .
Kusalananda

Soruda, iyi değil, anladım, ama sorun aynı "find:` `-exec '' için eksik argüman, Sorun farklı-2 sebepten kaynaklanabilir, ben de aynı sorun ifadesini gördüğüm için cevap verdim.
ShreePool

@Kusalananda iyi keder, noob bildirilen hata için OP tarafından soru ve başlık hem de belirtilen bir çözüm sağladı.
bvj

@bvj Soru açıkça seçeneğin +biçimi -execile ilgilidir find. Bu yanıt, soruyu soran kullanıcının sahip olmadığı bir sorunu düzeltiyor.
Kusalananda

-1

Geçmişte exec sözdizimi ile baş ağrımdan pay aldım. şimdi en güzel bash sözdizimini tercih ederim:

for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done

Her biri seri olarak değerlendirildiğinden, dosyaları bir grup olarak işlemek istediğinizde bazı sınırlamaları vardır, ancak çıktıyı başka bir yerde borulandırabilirsiniz


1
Bu çalışma eğilimindeyken, adında boşluk bulunan dosyaları doğru şekilde işleyemediğinden, salt bulma sürümünden önemli ölçüde daha az kullanışlıdır.
Etan Reisner

5
Hayır, yapma. Dosyalar boşluklar ve diğer “garip” karakterler içerdiğinde bu kesilir. Bu da daha karmaşık ve daha yavaştır find … -exec … \;, bu nedenle dosya adlarınızın uysal olduğunu bilseniz bile bunu kullanmanız için bir neden yoktur.
Gilles 'SO- kötü olmayı kes'

Bu, dosya adlarına (karakter kaldırma, dizin oluşturma ve daha sonra dosyaları taşıma gibi) dayalı birden çok mantık satırı çalıştırmak için gereken durumum için yararlı oldu. Birinde birden fazla şey yapmak için bulmaya çalışırken exec, bu harcamak istedim 5 dakika boyunca çok fazla bir baş ağrısı oldu. Dosya
adlarım uysaldı
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.