'Find -exec' dosya adlarını boşluklu olarak nasıl iletir?


14

Adları boşluk olan bazı dosyaları içeren bir dizin varsa, örneğin

$ ls -1 dir1
file 1
file 2
file 3

Hepsini böyle bir dizine başarıyla kopyalayabilirim:

$ find dir1 -mindepth 1 -exec cp -t dir2 {} +

Ancak, çıktısı find dir1 -mindepth 1kaçan boşluklar içeriyor:

$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3

print0Bunun yerine kullanırsanız print, çıktı hala kaçan boşluklar içeriyor:

$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3

Bu dosyaları elle kopyalamak cpiçin boşluklardan kaçmam gerekir; ama görünüşe bakılırsa, kullanmamdan bağımsız olarak veya komutun sonunda, cpnesneler geldiğinde bu gereksizdir .find+\;

Bunun sebebi ne?

Yanıtlar:


8

findKomutu doğrudan komutu yürütür. Dosya adı bağımsız değişkeni dahil olmak üzere komut, kabuk veya dosya adını değiştirebilecek başka bir şey tarafından işlenmez. Çok güvenli.

Sen tarafından temsil edilir dosya kaçmaya gerek yok o doğru {}üzerinde findkomut satırından.

findham dosya adını diskten doğrudan -execkomutunuzun iç bağımsız değişken listesine ( sizin durumunuzda, cpkomut) geçirir .


1
Özetle, find..execgarip dosya adlarını kendi başlarına
halledebilir

2
Linux kulübünün ilk kuralı sen ls ayrıştırmak değil
Sergiy Kolodyazhnyy

5

Soru iki bölümden oluşuyor:

  • nasıl yok find kullanarak çağrı programlarına yönetmek -execdosya adlarında gömülü boşluklar sorun haline çalıştırmadan ve
  • -print0seçenek ne kadar iyi ?

Birincisi, findbir sistem çağrısı yapmak, aslında "exec" olarak adlandırılan ilgili gruplardan biri . Dosya adını doğrudan bu çağrıya bir argüman olarak iletir; bu çağrı daha sonra dosya adı hakkında bilgi kaybetmeden doğrudan (yeni bir işlem oluşturduktan sonra) geçirilir.

POSIX findözelliği gerekçede+ şu şekilde açıklanmıştır :

SVR4'ün findyardımcı programının bir özelliği -execbirincil + sonlandırıcıydı. Bu, özel karakterler (özellikle yeni satır karakterleri) içeren dosya adlarının, bu tür dosya adlarına bağlanırsa ortaya çıkan sorunlar olmadan birlikte gruplanmasına izin verdi xargs. Diğer uygulamalar, özellikle -print0boş bir bayt sonlandırıcıyla dosya adları yazan bir birincil olan bu sorunu aşmanın başka yollarını da ekledi . Bu burada kabul edildi, ancak benimsenmedi. Boş bir sonlandırıcı kullanmak, find'ın -print0çıktısını işleyecek herhangi bir yardımcı programın, şimdi okuyacağı boş sonlandırıcıları ayrıştırmak için yeni bir seçenek eklemesi gerektiği anlamına geliyordu .

Bu " özellikle bir -print0birincil" GNU belirtir findve xargsbu, farklı bir şekilde sorunu çözmek. Ayrıca FreeBSD findve xargs. Çağrıya bir -0seçenek eklediyseniz ( kılavuz sayfasına bakın ) xargs, bu program "boş bayt" karakterleri ile sonlandırılmış satırları kabul eder. Buna karşılık, xargsaramaları exec yapmak -functions onun çalışmalarını. -print0Ve -0özelliği ile özellik arasındaki ana ayrım +, birincisinin dosya adlarını bir boru üzerinden geçirmesi, ikincisinin ise bir boru üzerinden geçirmesidir. Geliştiriciler hemen hemen her özellik için kullanım alanı bulur; borular bir istisna değildir.

Aşağıdakiler için bir -tseçenek kullanan OP örneğine dönün cp: POSIX cp'de bulunamadı . Aksine, GNU cp tarafından sağlanan bir uzantıdır (diğer bir deyişle "standart dışı özellik") . -0Uzatılması xargsBu örneği yükseltmekle kalmayacak, ancak taşınabilir alternatif olmadığını akılda etkili bir tutma kullanılabilecek başka durumlar da vardır +, GNU findkabul eder.


-1

( Bu bir yorum olmalı, ancak çok büyük. )

Bir şeyler denemek isteyenler için:

Aktarılan konum parametrelerini listeleyen bir komut dosyası oluşturun, onu çağırın list_positional_parameters.sh.

#!/bin/bash

# http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html
# Try globbing patterns, e.g. "X[[:digit:]][[:digit:]]" to see what happens

if [ $# -lt 1 ]; then
   echo "Usage: $0 and then at least one parameter"
   exit 1
fi

counter=1

while (($#)); do
   echo "$counter = '$1'"
   # pop positional argument 1 off the stack of positional arguments
   shift
   (( counter++ ))
done

Onunla findbazı dizinde çalıştırın $ dir:

find "$dir" -exec ./list_positional_parameters.sh '{}' ';' | less

Beklendiği gibi, adında boşluk olsun veya olmasın, tüm aramalarda yalnızca tek bir parametre vardır, dosya adı.


1
Görsel inceleme için alıntılanan tüm konumsal argümanları yazdırmak için printfbeğen gibi kullanabilirsiniz printf '"%s"\n' "$@".
Kusalananda
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.