好的,我的問題如下,我希望透過這個:-
echo $(($(date +%s%N)/1000000))
可以將其添加到變數“a”中,如下所示:-
a=$(($(date +%s%N)/1000000))
我這樣做的原因是想要使用 4 個隨機數字(隨機數)。我製作了這個 bash 腳本來展示一個例子。
#!/bin/bash
for (( c=0; c<=10; c++))
do
echo $(($(date +%s%N)/1000000))
sleep .5
done
哪個輸出:-(忽略前 9 位數字)
1622001937610
1622001938249
1622001938758
1622001939267
1622001939774
1622001940282
1622001940790
1622001941299
1622001941807
1622001942315
1622001942823
現在我想將其中一個實例的結果添加到一個數組中,從最後 9 位數字開始索引,以接收基於納秒時間的 4 個隨機數字。
然而我似乎沒有完全掌握 bash 中使用的語法來實現結果。我可以date +%s%N)/1000000
直接呼叫數組嗎?因為我的想法是創建並清空數組,然後將結果附加到數組中,並從第 9 個數字開始索引。並將結果傳遞到我可以處理的第二個變數中。
只要學習將 的結果轉換date +%s%N)/1000000
為變數就會有很大的幫助。
抱歉讓你很痛苦。提前謝謝您。
答案1
我最初的方法是對輸出使用字串處理date
來獲取所需的值。這裡的版本使用數學處理(除以 1000000,模 10000),但我已經為您留下了評論的替代方案
#!/bin/bash
items=()
random=$(( ($(date +%s%N) / 1000000) % 10000 )) # Second and milliseconds
# random=$( date +%s%N | grep -oP '....(?=......$)' )
items+=($random) # Append value to array
echo "${items[0]}" # First array value
echo "${items[-1]}" # Last (most recently appended) value
declare -p items # Visual inspection of array elements
答案2
您可以使用${var:offset:length}
參數擴充語法提取值的子字串:
$ nanoseconds=$(date +%N)
$ printf '%s\n' "$nanoseconds" "${nanoseconds:2:4}"
785455000
5455
或者,按照建議,使用 /dev/urandom:
$ tr -dc '[:digit:]' < /dev/urandom | fold -w 4 | head -n 10
8386
9194
3897
8790
4738
1453
4323
9021
6033
8889
使用 bash 命令將其讀入數組mapfile
:
$ mapfile -t numArray < <(tr -dc '[:digit:]' < /dev/urandom | fold -w 4 | head -n 10)
$ declare -p numArray
declare -a numArray=([0]="2851" [1]="9684" [2]="5823" [3]="5206" [4]="3208" [5]="2914" [6]="0395" [7]="4128" [8]="1876" [9]="5691")
答案3
如果運行date +%s%N
,輸出看起來像這樣:
1622046533072036066
ssssssssssmmmuuunnn
右邊的數字表示較小的單位。 ( m
//u
代表n
毫/微/奈秒。)
如果將其除以 1000000,就像$(( ... / 1000000))
這樣,您將刪除最右邊的六位數字,只留下秒和毫秒。
這些並不是很隨機。例如,在您的測試運行中,連續輸出數字以某種程度一致的 508 增加,這以毫秒為單位與您要求的 0.5 秒非常匹配。
如果你改為,你可能會得到更多隨機值保留最右邊的數字,並刪除前導數字,例如使用模運算子$(( ... % 1000000))
.儘管如果系統沒有足夠細粒度的時鐘,最低數字也可能不是很隨機。
如果只保留低位數字,則實際上不需要輸出date
完整的秒數,而是可以只使用+%N
,除了納秒值始終用零填充到 9 位數字,並且 Bash 將以零開頭的數字視為八進制,因此例如092345678
會產生錯誤。在前面加上一個額外的數字可以防止這種情況發生,但添加秒值也可以防止這種情況發生。
在我的系統上,以下循環的連續迭代的值之間的差異大致在 1470000 到 1560000 ns 的範圍內(約 1.5 毫秒/迭代),因此我可能不會使用超過四個最右邊的數字。
#/bin/bash
array=()
prev=$(date +%s%N)
for ((i=0; i < 100; i++)); do
this=$(date +%s%N)
# diff=$(( (this - prev) % 1000000000))
diff=$(( (this - prev) % 10000))
printf "$prev $this %04d\n" "$diff"
array+=("$diff")
prev=$this
done
除了算術之外,我們還可以將輸出視為date
字串,並截掉一些字元。這將留下最後 4 個字元:
a=$(date +%N)
a=${a: -4}
話又說回來,人們可以考慮其他方式來產生隨機數,例如shuf
從 GNU coreutils,它不僅限於洗牌,還可以透過重複來選擇值。例如,這將列印 20 個數字,每個數字 4 位數:
shuf -i 0000-9999 -r -n 20
或用一些箍來獲得零填充:
shuf -i 10000-19999 -r -n 20 |sed -e 's/^1//'
您可以使用以下命令將輸出讀取到陣列readarray
:
readarray array < <(shuf -i 0000-9999 -r -n 20)
毫不奇怪,shuf
它比在 shell 中循環呼叫 快得多date
。您也可以使用較小的範圍,例如-i 0-9
取得單位數。