Sadece iki sayıyı dcbenzerleriyle karşılaştırabilirsiniz:
dc -e "[$1]sM $2d $1<Mp"
... "$1"maksimum değeriniz nerededir ve "$2"daha küçükse yazdıracağınız sayıdır "$1". Bu ayrıca GNU’yu da gerektirir dc- ancak aynı şeyi taşınabilir şekilde yapabilirsiniz:
dc <<MAX
[$1]sM $2d $1<Mp
MAX
Yukarıdaki durumların her ikisinde de, hassasiyeti 0 (varsayılan) gibi bir şeyden başka bir değere ayarlayabilirsiniz ${desired_precision}k. Her ikisi için de, her iki değerin de kesinlikle sayılar olduğunu doğrulamanız zorunludur, çünkü operatörle arama dcyapabilir .system()!
Aşağıdaki küçük betiği kullanarak (ve sonrakini) girişi grep -v \!|dcisteğe bağlı olarak sağlam bir şekilde işleyebilecek bir şey gibi doğrulamanız gerekir . Ayrıca, dcnegatif sayıları _önek yerine önekle yorumladığını da bilmelisiniz -- çünkü ikincisi çıkarma işlecidir.
Bunun dışında, bu komut dosyasıyla dc, \nsağlamak istediğinize göre sırayla dizilmiş ewline ayrılmış sayıları okuyacak ve wo'nun $maxhangisinin daha az olduğuna bağlı olarak her biri için değerinizi veya girişinizi yazdıracaksınız :
dc -e "${max}sm
[ z 0=? d lm<M p s0 lTx ]ST
[ ? z 0!=T q ]S?
[ s0 lm ]SM lTx"
Yani ... Bunların her birini [kare parantez ]expanses bir olduğunu dc dize olan nesne Sherhangi biri - kendi ilgili diziye her aved T, ?ya M. dcBir dize ile yapılabilecek bazı diğer şeylerin yanı sıra x, bir makroyu aynı zamanda ekleyebilme. Doğru düzenlerseniz, tamamen işleyen küçük bir dcsenaryo yeterince basit bir şekilde derlenir.
dcbir yığın üzerinde çalışıyor . Tüm giriş nesneleri, her biri en üste istiflenir - her yeni giriş nesnesi, son üst nesneye ve altındaki tüm nesnelere yığılmış olarak yığılmış olarak aşağıya itilir. Bir nesneye en referanslar üst yığın değerine ve çoğu referanslar pop yığının bu üst (tek altındaki tüm nesneleri yukarı çeker) .
Ana yığının yanı sıra, ayrıca (en az) 256 dizi vardır ve her bir dizi öğesi, kendi başına bir yığınla birlikte gelir. Burada fazla kullanmıyorum. Ben böylece belirtildiği gibi sadece dizeleri depolamak listediği zaman onları OAD ve e xşartlı ecute onları ve ben syırttı $maxüst 'nin değerini mdizisi.
Her neyse, bu küçük parça, dckabuk betiğinin ne yaptığını büyük ölçüde yapıyor. GNU-ism -eseçeneğini kullanır - dcgenel olarak parametrelerini standarttan alır - ancak aynısını yapabilirsiniz:
echo "$script" | cat - /dev/tty | dc
... eğer $scriptyukarıdaki bit gibi görünüyorsa.
Gibi çalışır:
lTx- Bu lyuvarlanır ve xen üstte bulunan makroyu alır T (test için sanırım - genellikle bu adları rasgele seçerim) .
z 0=?- Test sonra yığın derinliğini w / test eder zve yığın boşsa (okuma: 0 nesne tutar)? makro çağırır .
? z0!=T q- ?Makro, ? dcstdin'den bir girdi satırı okuyan yerleşik komut için adlandırılır , ancak aynı zamanda başka bir zyığın derinlik testi de ekledim , böylece qboş bir çizgi çekerse ya da EOF'ye çarparsa bütün küçük programa uyabilir. Ancak !yığını doldurmaz ve başarılı bir şekilde doldurursa, Ttekrar est çağırır .
d lm<M- Test daha sonra dyığının tepesini çoğaltacak ve $max (içinde saklandığı gibi m) ile karşılaştıracaktır . Daha mdüşük bir değer ise, makro dcçağırır M.
s0 lm- Msadece yığının üstünü çıkarır ve onu aptalca skalaya atar 0- yığını yığmanın sadece ucuz bir yolu. Ayrıca , est 'e dönmeden önce tekrar lses çıkarır .mT
p- Bu m, mevcut yığının tepesinden daha az ise, o zaman monu değiştirir ( dyinelenen, yine de) ve burada pkesilir, aksi halde girmez ve giriş ne olursa olsun, pbunun anlamı gelir.
s0- Sonra ( pyığını yığmadığı için) yığının tepesini 0tekrar dolduruyoruz ve sonra ...
lTx- yinelemeli lOAD Test kez daha sonra e xecute bunu tekrar.
Böylece bu küçük pasajı çalıştırabilir ve etkileşimli olarak terminalinize sayıları yazabilir ve dcgirdiğiniz sayıyı veya $maxyazdığınız sayı daha büyükse , değeri size geri yazdırabilirsiniz . Ayrıca herhangi bir dosyayı (bir boru gibi) standart girdi olarak kabul eder . Boş bir satıra veya EOF ile karşılaşana kadar okuma / karşılaştırma / yazdırma döngüsüne devam edecektir.
Bununla ilgili bazı notlar - Kabuk fonksiyonunuzdaki davranışı taklit etmek için yazdım, bu yüzden satır başına yalnızca bir sayı sağlam bir şekilde ele alınıyor. dcBununla birlikte, satır başına atmak istediğiniz gibi satır başına boşlukla ayrılmış sayıları kullanabilirsiniz. Bununla birlikte , yığından dolayı satırdaki son sayı, üzerinde çalıştığı ilk dcsayıdır ve satır başına birden fazla sayı yazdıysanız / yazdıysanız, yazıldığı gibi çıktısını tersine basar. bununla baş etmek için bir diziyi bir satırda saklamak, sonra çalışmaktır.
Bunun gibi, böyle:
dc -e "${max}sm
[ d lm<M la 1+ d sa :a z0!=A ]SA
[ la d ;ap s0 1- d sa 0!=P ]SP
[ ? z 0=q lAx lPx l?x ]S?
[q]Sq [ s0 lm ]SM 0sa l?x"
Ama ... Bunu çok derinlemesine açıklamak isteyip istemediğimi bilmiyorum. dcYığındaki her bir değerde okuduğu gibi değerini veya $maxdeğerini indeksli bir dizide sakladığını ve yığının bir kez daha boş olduğunu algıladığında, başka bir okumaya çalışmadan önce her indekslenmiş nesneyi yazdırdığını söylemek yeterlidir. giriş hattı.
Ve böylece, ilk senaryo da ...
10 15 20 25 30 ##my input line
20
20
20
15
10 ##see what I mean?
İkinci yapar:
10 15 20 25 30 ##my input line
10 ##that's better
15
20
20 ##$max is 20 for both examples
20
Komutla ilk kez ayarlarsanız, keyfi kesinlikteki değişkenleri kullanabilirsiniz k. Ve igiriş veya oçıkış çaplarını bağımsız olarak değiştirebilirsiniz - bu bazen beklemeyebileceğiniz nedenlerden dolayı yararlı olabilir. Örneğin:
echo 100000o 10p|dc
00010
... ilk önce dcçıkış yarıçapını 100000 değerine ayarlayan sonra 10 basar.