將日期命令傳遞給變數?

將日期命令傳遞給變數?

好的,我的問題如下,我希望透過這個:-

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取得單位數。

相關內容