Cp komutuyla düzenli ifadeleri Linux'ta nasıl kullanırsınız?


22

Yalnızca bir alt dizini bir dizinden diğerine kullanarak kopyalamaya çalışıyorum cpancak mesajla karşılanıyorum cp: cannot stat [^\.php]': No such file or directory. Yalnızca cpkomutu kullanarak normal ifadeleri kullanmanın bir yolu var mı ?

Yanıtlar:


29

Yok hayır.

cpKomut normal ifadeler olarak Bağımsız değişkenlerinin herhangi işlemek için yeteneği sahip değildir. Joker karakterler bile onun tarafından işlenmez (veya çoğu çalıştırılabilir); bunun yerine kabuk tarafından ele alınırlar.

cp test/* test2/gerçekte bash tarafından genişletilir cpve argümanları için gerçekten gören cp test/file1 test/file2 test/file3 test2/her şey (veya asıl içeriğe göre uygun olanı test/).

Ayrıca, ifadenizin [^\.php]istediğinizi eşleştireceğini sanmıyorum (yalnızca içeren dosyaları eşleştirmiyor .php).

Muhtemelen find, düzenli ifadeye dayanan bir dosya listesini filtrelemek için yardımcı programa bakmak istersiniz ve daha sonra xargsgeri gönderilen dosya listesini cpkomuta uygulamak için kullanabilirsiniz (bulma, dosyaları kopyalamak için yerleşik bir işleyiciye sahip olmadığını varsayarak; m aracı yakından tanımadım).

Deneyebilirsin:

find . ! -iregex ".*\.php.*" -exec cp {} /destination/folder/ \;

Bu, geçerli dizini yolunda ".php" içermeyen dosyaları yinelemeli olarak araştırıp kopyaladığınızı söylüyor /destination/folder/.

İstenildiği gibi, argümanların daha ayrıntılı bir dökümü:

  • . - Aramayı başlatmak için konum - bu durumda, geçerli dizin
  • ! - "Değil" operatörü, bir sonraki testin sonucunu ters çevirin
  • -iregex- Harf duyarsız düzenli ifade testi. Sonraki argüman ifadedir.
  • ".*\.php.*"- Düzenli ifade eşleştirmesi <Anything>.php<Anything>- Yolda bir yerde ".php" olan herhangi bir dosya. (Adında ".php" içeren bir klasörün içinde olmak dahil, yalnızca dosyalarla eşleşmesi için daha karmaşık bir ifadeye ihtiyacınız olacağını unutmayın)
  • -exec- Yukarıdaki testler doğru olursa, bir komut verin. Sonraki argüman komuttur, kalan tüm argümanlar ;komuta iletilir. {}dosya temsil özel bir argümandır.
  • cp - Bulunan komut, eşleşen yol adlarının her birinde çalıştırılmalıdır.
  • {}- Bulunan dosyanın yolu, cphangi dosyanın kopyalanacağını bilmesi için bir argüman olarak iletilir.
  • /destination/folder/- argümanı geçirilen cpsöylüyorum, cpo dosyayı kopyalamak gereken yerde.
  • \;- Bu arayan ;sonlandırıcı -exec. Ondan kaçıyoruz, \böylece kabuğunuz ayrıştırmaya kalkar ve bunun yerine komutu argüman olarak besler ( find)

"Sahip olmayan dizeleri" ile eşleşen düzenli bir ifade yazmak oldukça zor .php, bu yüzden bunun yerine sonuçları içeren finddizeleri aramayı ve sonraları tersine çevirmeyi söylüyoruz ..php!


2
find . -name [^\.php] -exec cp {} /path/to/location \;özel karakterli dosyalar için dikkatli olun.
Rob

@Darth Android - Teşekkürler. Ben farkında değildim cpdiğer ikili düzenli ifadeleri genişletmek mümkün değildi ve. Verdiğiniz örnek örnekte, seçeneklerin ve argümanların her birinin ne anlama geldiğini ayrıntılandırabilir misiniz? Bunu biliyorum .geçerli dizine karşılık gelir ama ne yapmak !, {}, \;vb ne anlama geldiklerini de ifade? Mesela neden kaçmak zorundasın ;?
FıstıkMonkey 20

@Rob - Özel dosyalar derken neyi kastediyorsunuz?
FıstıkMonkey 20

@Rob - Belirli dosyaları silmek için benzer bir ifade denedim ancak dizindeki tüm dosyaları sildim. Benim emrim, find . -name '[^\.txt]' -exec rm {} \;bu yüzden kullanma konusundaki isteksizliğimdi find. Muhtemelen benim açımdan bir hata ama neyi yanlış yaptığımdan emin değilim. Anladığım kadarıyla {}komut tarafından bulunan her dosyaya atıfta bulunuyorumfind . -name '[^\.txt]'
PeanutsMonkey

Regex ile ne eşleştirmeye çalışıyorsun?
Rob

10

Grep ve xargs gibi konsoldan başka birkaç araç kullanabilirsiniz.

ls -1 some_folder | egrep 'some_extended_regex' | xargs cp -t destination_folder

Bundan {}farklı ne olabilir -t?
FıstıkMonkey

2
Bu durumda pek değil. Xargs için alternatif sözdizimi 'xargs cp {} destination_folder' olur. Standart cp sözdizimi sonunda bir veya daha fazla kaynak ve bir hedef alır, -t seçeneğini kullandığınızda, -t'den sonra hedefi belirtebilir ve sonra kaynaklar için satırın kalanını kullanabilirsiniz. Ben sadece -t seçeneğini bu durumda daha uygun buluyorum. Diğer örnekte, {}, xargs (stdin) 'a aktarılanla değiştirilir, bu durumda dosya adı.
12'de

-1

Kullanımı kolay aşağıdaki komutu çalıştırabilirsiniz:

find /home/usr/search_dir -iname *file_name_portion*.txt | xargs cp -t /home/usr/destination_folder

haa haa !!

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.