İlk önemsiz ama uygulanamaz cevapları kapalı kesim için: Ben ne kullanabilirsiniz find
+ xargs
hile ne de (gibi varyasyonlarını find
ile -exec
ben görüşme başına kaç tür ifadeleri kullanmak gerekir çünkü). Sonunda buna geri döneceğim.
Şimdi daha iyi bir örnek için şunu düşünelim:
$ find -L some/dir -name \*.abc | sort
some/dir/1.abc
some/dir/2.abc
some/dir/a space.abc
Bunları nasıl argüman olarak aktarabilirim program
?
Sadece yapmak hile yapmaz
$ ./program $(find -L some/dir -name \*.abc | sort)
program
aşağıdaki argümanları aldığından beri başarısız olur:
[0]: ./program
[1]: some/dir/1.abc
[2]: some/dir/2.abc
[3]: some/dir/a
[4]: space.abc
Görülebileceği gibi, uzaylı yol ayrıldı ve program
onu iki farklı argüman olarak görüyor.
Çalışana kadar alıntı yap
Kendim gibi acemi kullanıcılar, bu tür sorunlarla karşılaştıklarında, nihayet işe yarayana kadar rastgele tırnak ekleme eğilimindedir - sadece burada yardımcı görünmüyor…
"$(…)"
$ ./program "$(find -L some/dir -name \*.abc | sort)"
[0]: ./program
[1]: some/dir/1.abc
some/dir/2.abc
some/dir/a space.abc
Tırnaklar kelime bölünmesini engellediğinden, tüm dosyalar tek bir argüman olarak iletilir.
Bireysel yolları alıntılama
Gelecek vaat eden bir yaklaşım:
$ ./program $(find -L some/dir -name \*.abc -printf '"%p"\n' | sort)
[1]: "some/dir/1.abc"
[2]: "some/dir/2.abc"
[3]: "some/dir/a
[4]: space.abc"
Alıntılar var, tabi. Ama artık yorumlanmıyorlar. Onlar sadece dizelerin bir parçası. Yani sadece kelime bölünmesini engellemediler, aynı zamanda argümanlara da girdiler!
IFS'yi değiştirin
Sonra ile oynamayı denedim IFS
. Ben tercih ediyorum find
ile -print0
ve sort
ile -z
yine - onlar "kablolu yolları" kendileri üzerinde hiçbir sorunları olacak böylece. Öyleyse neden kelimeyi null
karaktere ayırmaya zorlamıyorsunuz ve hepsine sahip misiniz?
$ ./program $(IFS=$'\0' find -L some/dir -name \*.abc -print0 | sort -z)
[0]: ./program
[1]: some/dir/1.abcsome/dir/2.abcsome/dir/a
[2]: space.abc
Bu yüzden hala uzaya ayrılıyor ve üzerinde bölünmüyor null
.
IFS
Ödevi hem $(…)
yukarıda (yukarıda gösterildiği gibi) hem de daha önce yerleştirmeye çalıştım ./program
. Ayrıca ben gibi diğer sözdizimi çalıştı \0
, \x0
, \x00
hem alıntı '
ve "
olan ve olmayan yanı sıra $
. Bunların hiçbiri fark yaratmadı ...
Ve burada fikirlerim kalmadı. Birkaç şey daha denedim ama hepsi listelenen aynı sorunları koşmak gibi görünüyordu.
Başka ne yapabilirdim? Hiç yapılabilir mi?
Tabii, program
kalıpları kabul edebilir ve kendi aramaları yapabilirim. Ancak belirli bir sözdizimine sabitlerken çok fazla çift çalışma var. ( grep
Örneğin, dosyaları bir dosya ile sağlamaya ne dersiniz ?).
Ayrıca program
yolların listesini içeren bir dosyayı kabul edebilirim. Sonra kolayca find
bazı geçici dosyaya ifade dökümü ve sadece bu dosyaya yol sağlayabilir. Bu, doğrudan yollar boyunca desteklenebilir, böylece kullanıcı sadece basit bir yola sahipse, ara dosya olmadan sağlanabilir. Ancak bu hoş görünmüyor - bir kişinin ekstra dosyalar oluşturması ve bunlarla ilgilenmesi gerekiyor, gerekli ekstra uygulamadan bahsetmiyoruz. (Ancak, artı tarafta, bağımsız değişken olarak dosya sayısının komut satırı uzunluğu ile ilgili sorunlara neden olduğu durumlar için bir kurtarma olabilir ...)
Sonunda, tekrar hatırlatmama izin verin ki find
+ xargs
(ve benzer) numaralar benim durumumda işe yaramayacak. Açıklama basitliği için sadece bir argüman gösteriyorum. Ama benim gerçek durumum daha çok şöyle görünüyor:
$ ABC_FILES=$(find -L some/dir -name \*.abc | sort)
$ XYZ_FILES=$(find -L other/dir -name \*.xyz | sort)
$ ./program --abc-files $ABC_FILES --xyz-files $XYZ_FILES
Yani xargs
bir arama yapmak hala diğeri ile başa çıkmak için bana bırakıyor…
mapfile
(ya da eşanlamlısıreadarray
). Ama işe yarıyor!