Bạn có thể so sánh chỉ hai số với dc
thích:
dc -e "[$1]sM $2d $1<Mp"
... "$1"
giá trị tối đa của bạn ở đâu và "$2"
là số bạn sẽ in nếu nó nhỏ hơn "$1"
. Điều đó cũng đòi hỏi GNU dc
- nhưng bạn có thể làm điều tương tự như:
dc <<MAX
[$1]sM $2d $1<Mp
MAX
Trong cả hai trường hợp trên, bạn có thể đặt độ chính xác thành giá trị khác 0 (mặc định) như thế nào ${desired_precision}k
. Đối với cả hai điều bắt buộc là bạn xác minh rằng cả hai giá trị đều là số chắc chắn vì dc
có thể thực hiện system()
cuộc gọi với !
nhà điều hành.
Với tập lệnh nhỏ sau (và tiếp theo), bạn nên xác minh đầu vào cũng giống như grep -v \!|dc
hoặc một cái gì đó để xử lý mạnh mẽ đầu vào tùy ý. Bạn cũng nên biết rằng dc
diễn giải các số âm với _
tiền tố chứ không phải -
tiền tố - bởi vì cái sau là toán tử trừ.
Ngoài ra, với tập lệnh dc
này sẽ đọc thành nhiều số \n
ewline được phân tách liên tiếp như bạn muốn cung cấp và in cho từng $max
giá trị của bạn hoặc đầu vào, tùy thuộc vào số nào nhỏ hơn của wo:
dc -e "${max}sm
[ z 0=? d lm<M p s0 lTx ]ST
[ ? z 0!=T q ]S?
[ s0 lm ]SM lTx"
Vì vậy, ... mỗi người trong số những [
ngoặc vuông ]
expanses là một dc
chuỗi đối tượng đó là S
aved từng đến mảng tương ứng của nó - bất kỳ một trong T
, ?
hoặc M
. Bên cạnh một số điều khác dc
có thể làm với một chuỗi , nó cũng có thể tính toán một chuỗix
như một macro. Nếu bạn sắp xếp nó đúng, một dc
kịch bản nhỏ đầy đủ chức năng được lắp ráp đủ đơn giản.
dc
hoạt động trên một ngăn xếp . Tất cả các đối tượng đầu vào được xếp chồng lên nhau lần cuối - mỗi đối tượng đầu vào mới đẩy đối tượng trên cùng cuối cùng và tất cả các đối tượng bên dưới nó xuống trên ngăn xếp bởi một khi nó được thêm vào. Hầu hết các tham chiếu đến một đối tượng là giá trị ngăn xếp trên cùng và hầu hết các tham chiếu bật lên trên cùng của ngăn xếp (kéo tất cả các đối tượng bên dưới nó lên một) .
Bên cạnh ngăn xếp chính, còn có (ít nhất) 256 mảng và mỗi phần tử mảng đi kèm với một ngăn xếp riêng. Tôi không sử dụng nhiều ở đây. Tôi chỉ lưu trữ các chuỗi như đã đề cập để tôi có thể l
tải chúng khi muốn và tính x
toán chúng một cách có điều kiện và tôi s
xé $max
giá trị của nó ở đầu m
mảng.
Dù sao, phần nhỏ dc
này, phần lớn, những gì shell-script của bạn làm. Nó sử dụng -e
tùy chọn GNU-ism - như dc
thường lấy các tham số của nó từ tiêu chuẩn - nhưng bạn có thể làm tương tự như sau:
echo "$script" | cat - /dev/tty | dc
... Nếu $script
trông giống như bit trên.
Nó hoạt động như:
lTx
- Điều này l
tải và e tính x
toán macro được lưu trữ ở đầu T
(để kiểm tra, tôi đoán - tôi thường chọn các tên đó một cách tùy ý) .
z 0=?
- T
est sau đó kiểm tra độ sâu ngăn xếp w / z
và, nếu ngăn xếp trống (đọc: giữ 0 đối tượng) thì nó gọi ?
macro.
? z0!=T q
- ?
Macro được đặt tên cho ?
dc
lệnh dựng sẵn đọc một dòng đầu vào từ stdin, nhưng tôi cũng đã thêm một z
bài kiểm tra độ sâu ngăn xếp khác cho nó, để nó có thể phù hợp q
với toàn bộ chương trình nếu nó kéo vào một dòng trống hoặc chạm vào EOF. Nhưng nếu nó !
không và thay vào đó cư trú thành công ngăn xếp, nó sẽ gọi T
lại est.
d lm<M
- T
est sau đó sẽ d
tăng đỉnh của ngăn xếp và so sánh nó với $max
(như được lưu trữ trong m
) . Nếu m
là giá trị nhỏ hơn, dc
gọi M
macro.
s0 lm
- M
chỉ cần bật đỉnh của ngăn xếp và đổ nó vào vô hướng giả 0
- chỉ là một cách rẻ tiền để bật ngăn xếp. Nó cũng l
tải m
lại một lần nữa trước khi trở về T
est.
p
- Điều này có nghĩa là nếu m
nhỏ hơn đỉnh ngăn xếp hiện tại, thì hãy m
thay thế nó ( d
dù sao thì nó cũng được thay thế) , ở đây p
không phải là gì và thay vào đó là bất cứ thứ gì đầu vào được p
thay thế.
s0
- Sau đó (vì p
không bật ngăn xếp), chúng ta sẽ đổ đỉnh ngăn xếp 0
lại, và sau đó ...
lTx
- đệ quy l
oad T
est một lần nữa sau đó e x
tính lại.
Vì vậy, bạn có thể chạy đoạn mã nhỏ này và nhập số tương tác tại thiết bị đầu cuối của mình và dc
sẽ in lại cho bạn số bạn đã nhập hoặc giá trị $max
nếu số bạn nhập lớn hơn. Nó cũng sẽ chấp nhận bất kỳ tập tin nào (như đường ống) làm đầu vào tiêu chuẩn. Nó sẽ tiếp tục vòng lặp đọc / so sánh / in cho đến khi gặp một dòng trống hoặc EOF.
Một số lưu ý về điều này mặc dù - tôi đã viết điều này chỉ để mô phỏng hành vi trong hàm shell của bạn, vì vậy nó chỉ xử lý mạnh mẽ một số trên mỗi dòng. dc
tuy nhiên, có thể xử lý bao nhiêu số cách nhau trên mỗi dòng mà bạn quan tâm để ném vào nó. Tuy nhiên , do ngăn xếp của nó, số cuối cùng trên một dòng sẽ là số đầu tiên mà nó hoạt động, và do đó, như đã viết, dc
sẽ in đầu ra của nó ngược lại nếu bạn in / gõ nhiều hơn một số trên mỗi dòng. để xử lý đó là lưu trữ một dòng trong một mảng, sau đó làm việc với nó.
Như thế này:
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"
Nhưng ... tôi không biết liệu tôi có muốn giải thích điều đó ở độ sâu không. Chỉ cần nói rằng khi dc
đọc từng giá trị trên ngăn xếp, nó sẽ lưu giá trị của nó hoặc giá trị của nó $max
trong một mảng được lập chỉ mục, và một khi nó phát hiện ngăn xếp lại một lần nữa, nó sẽ in từng đối tượng được lập chỉ mục trước khi cố đọc một đối tượng khác dòng đầu vào.
Và vì vậy, trong khi kịch bản đầu tiên làm ...
10 15 20 25 30 ##my input line
20
20
20
15
10 ##see what I mean?
Thứ hai không:
10 15 20 25 30 ##my input line
10 ##that's better
15
20
20 ##$max is 20 for both examples
20
Bạn có thể xử lý các float với độ chính xác tùy ý nếu trước tiên bạn đặt nó bằng k
lệnh. Và bạn có thể thay đổi các thông số i
hoặc o
thông số độc lập - đôi khi có thể hữu ích vì những lý do bạn có thể không mong đợi. Ví dụ:
echo 100000o 10p|dc
00010
... Đầu tiên thiết lập dc
cơ số đầu ra của nó thành 100000 sau đó in 10.