Yanıtlar:
İşte anlaşılması oldukça kolay bir POSIX çözümü:
find . -type f -exec awk -v x=10 'NR==x{exit 1}' {} \; -exec echo rm -f {} \;
Olduğu gibi Stephane'ın cevap kaldırmak echosilinecektir ne zaman mutlu.
Nokta .geçerli dizini temsil eder. finddosyaları ve dizinleri özyinelemeli olarak bulur ve .bunlarla bir şeyler yapabilir.
-typebiridir findbireyin primerler ; özyinelemeli (içinde .) bulunan her dosya ve dizin için yapılacak bir sınamadır ve satırdaki diğer ilkeler yalnızca "doğru" ile sonuçlanırsa değerlendirilir.
Bu özel durumda, yalnızca normal bir dosyayla uğraşıyorsak devam ediyoruz, bir dizin veya başka bir şeyle değil (ör. Bir blok cihazı).
-exec(Birincil find) bir dış komutu çağırır ve sadece bir sonraki birincil ilerler eğer başarılı dış komut çıkışlar ( "0" çıkış durumu). Bu {}, findkomut tarafından "dikkate alınan" dosya adıyla değiştirilir . Böylece ilk -execçağrı, her dosya için sırayla yürütülen aşağıdaki shell komutuna eşdeğerdir:
awk -v x=10 'NR==x{exit 1}' ./somefilename
Awk, CSV gibi sınırlandırılmış metin dosyalarını işlemek için tasarlanmış , kendi içinde bütün bir dildir . NRBir metin dosyasının her satırı için Awk koşulları ve komutları (tek tırnak işaretleri arasında ve harflerle başlar ) yürütülür. (Kapalı döngü.)
Awk'u tam olarak öğrenmek için Grymoire Tutorial'ı tavsiye ederim , ancak yukarıdaki komutta kullanılan Awk özelliklerini açıklayacağım.
-vAwk için bayrak bize Awk komutlar belirlediğimiz Bu durumda (dosyanın her satırı için.) İdam edilmeden önce bir Awk değişkeni (bir kez) ayarlamanızı sağlar xiçin 10.
NRatıfta özel awk değişkendir " K akımın koyu kahverengi R üzerindeki Record." Başka bir deyişle, döngüden herhangi bir geçişte baktığımız satır numarasıdır.
(O Not olan sıradışı olsa farklı bir "kullanmaya, olası R üzerindeki Record S ayarıyla, bir yeni satır karakteri varsayılan dışında eparator" RS. Burada kayıt ayırıcılar ile oynayan bir örnektir. )
Awk komut dosyaları genellikle eylemlerle (kıvırcık ayraçların içinde ) oluşan koşullardan (kıvırcık ayraçların içinde) oluşur . Bileşik koşullar ve bileşik eylemler olabilir ve varsayılan bir koşul (doğru) ve varsayılan bir eylem (baskı) olabilir, ancak ihtiyacımız var bunlarla uğraşma.
Buradaki koşul , "Bu 10. satır mı?" Bu durumda, kabuk komut dosyasında "başarısız komut sonlandırma" anlamına gelen sıfır olmayan bir çıkış durumuyla çıkarız.
Bu nedenle , bu Awk komutunun başarılı bir şekilde çıkmasının tek yolu , dosyanın 10. satıra ulaşılmadan sonuna ulaşılmasıdır.
Awk betiği başarıyla çıkarsa, on satırdan daha az bir dosyanız olduğu anlamına gelir.
Bir sonraki -execçağrı (eğer kaldırırsanız echo) çalıştırarak her bir dosyayı ( find'primerlerinin değerlendirilmesinde bu kadar ileri gider) kaldıracaktır :
rm -f ./somefilename
Yüklemi finddestekleyen bir uygulama olduğunu varsayarsak -readable(yüklemeniz desteklemiyorsa, findkaldırın, sadece okunamayan dosyalar için hata mesajları alırsınız veya bunun yerine değiştirebilirsiniz -exec test -r {} \;):
x=10 find . -type f -readable -exec sh -c '
for file do
lines=$(wc -l < "$file") && [ "$((lines))" -lt "$x" ] && echo rm -f "$file"
done' sh {} +
echoMutlu ise çıkarın .
Yani sayar o özellikle verimli değil tüm bu sadece durdurmak için ihtiyacı olduğu her dosyada satırları xinci biri ve tek çalıştırır wc(ve potansiyel olarak bir tane rm) her dosya için komutu.
GNU ile awkaşağıdakileri daha verimli hale getirebilirsiniz:
x=10
find . -type f -readable -exec awk -v x="$x" -v ORS='\0' '
FNR == x {nextfile}
ENDFILE {if (FNR < x) print FILENAME}' {} +|
xargs -r0 echo rm -f
(yine echomutlu olduğunda çıkarın ).
Aynı perl:
x=10 find . -type f -readable -exec perl -Tlne '
if ($. == $ENV{x}) {close ARGV}
elsif (eof) {print $ARGV; close ARGV}' {} +
Değiştir printile unlinkmutlu eğer.
sholarak satır içi komut dosyalarında $0hata iletileri için kullanılacak olan şeydir . wc -l "$file"burada istemediğimiz ve wcdosya açılamasa bile çalışacak olan dosya adını yazdırır . $xihraç edilmektedir find( x=10 find...kendisi için geçtiği) sh.
find: -readable: unknown primary or operator.
bash. bashsadece bir komut satırı yorumlayıcısıdır, fakat finduygulamadan ibarettir. -readablebir GNU oluşumudur, OS / X'te mevcut değildir find. Yalnızca okunabilir dosyaları sınırlamak için kullanılır (okunamayan dosyalar için satır sayısını alamazsınız). Birincisi için bunu atlayabilirsiniz, daha sonra wcokunamayan dosyalar için dosyaları açarken hata mesajları alırsınız .
Tamlık uğruna, AWK'nın yanı sıra, aynı sonucu elde etmek için GNU sed'i de kullanabilirsiniz:
find . -type f -exec sed 11q1 '{}' ';' -exec echo rm -f '{}' ';'
Hangi biraz daha özlü komut satırı ile sonuçlanır.
açıklama
11 - is the address, i.e. "the eleventh line"
q - is for _q_uit (abort the execution)
1 - is the exit code parameter for q (GNU sed extension)
shiçin? 2.wc -l < "$file"Daha hızlı mıwc -l "$file"? 3. sh$x, çağıran Bash kabuğunda tanımlanan değerini nasıl bilebilir ?