Sadece iki sayıyı dc
benzerleriyle 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 dc
yapabilir .system()
!
Aşağıdaki küçük betiği kullanarak (ve sonrakini) girişi grep -v \!|dc
isteğe bağlı olarak sağlam bir şekilde işleyebilecek bir şey gibi doğrulamanız gerekir . Ayrıca, dc
negatif sayıları _
önek yerine önekle yorumladığını da bilmelisiniz -
- çünkü ikincisi çıkarma işlecidir.
Bunun dışında, bu komut dosyasıyla dc
, \n
sağlamak istediğinize göre sırayla dizilmiş ewline ayrılmış sayıları okuyacak ve wo'nun $max
hangisinin 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 S
herhangi biri - kendi ilgili diziye her aved T
, ?
ya M
. dc
Bir 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 dc
senaryo yeterince basit bir şekilde derlenir.
dc
bir 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 l
istediği zaman onları OAD ve e x
şartlı ecute onları ve ben s
yırttı $max
üst 'nin değerini m
dizisi.
Her neyse, bu küçük parça, dc
kabuk betiğinin ne yaptığını büyük ölçüde yapıyor. GNU-ism -e
seçeneğini kullanır - dc
genel olarak parametrelerini standarttan alır - ancak aynısını yapabilirsiniz:
echo "$script" | cat - /dev/tty | dc
... eğer $script
yukarıdaki bit gibi görünüyorsa.
Gibi çalışır:
lTx
- Bu l
yuvarlanır ve x
en üstte bulunan makroyu alır T
(test için sanırım - genellikle bu adları rasgele seçerim) .
z 0=?
- T
est sonra yığın derinliğini w / test eder z
ve yığın boşsa (okuma: 0 nesne tutar)?
makro çağırır .
? z0!=T q
- ?
Makro, ?
dc
stdin'den bir girdi satırı okuyan yerleşik komut için adlandırılır , ancak aynı zamanda başka bir z
yığın derinlik testi de ekledim , böylece q
boş 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, T
tekrar est çağırır .
d lm<M
- T
est daha sonra d
yığının tepesini çoğaltacak ve $max
(içinde saklandığı gibi m
) ile karşılaştıracaktır . Daha m
düşük bir değer ise, makro dc
çağırır M
.
s0 lm
- M
sadece 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 l
ses çıkarır .m
T
p
- Bu m
, mevcut yığının tepesinden daha az ise, o zaman m
onu değiştirir ( d
yinelenen, yine de) ve burada p
kesilir, aksi halde girmez ve giriş ne olursa olsun, p
bunun anlamı gelir.
s0
- Sonra ( p
yığını yığmadığı için) yığının tepesini 0
tekrar dolduruyoruz ve sonra ...
lTx
- yinelemeli l
OAD T
est kez daha sonra e x
ecute bunu tekrar.
Böylece bu küçük pasajı çalıştırabilir ve etkileşimli olarak terminalinize sayıları yazabilir ve dc
girdiğiniz sayıyı veya $max
yazdığı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. dc
Bununla 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 dc
sayı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. dc
Yığındaki her bir değerde okuduğu gibi değerini veya $max
değ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 i
giriş 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.