2011-02-14 66 views

回答

11

wc可以告訴你變量中有多少個字符和字節,而bash本身可以告訴你數組中有多少個元素。如果你正在尋找的是多大的bash的內部結構是持有一個特定的變量,那麼我不相信這是可用的任何地方。

$ foo=42 
$ bar=(1 2 3 4) 
$ echo -n "$foo" | wc -c -m 
     2  2 
$ echo "${#bar[@]}" 
4 
+1

你可以寫$ {#foo}來獲得字符串的長度 - 查看我的回答 – 2011-02-14 06:17:17

+0

@Foo:在字符中,是的。不以字節爲單位。 – 2011-02-14 06:37:12

+0

如果您真的在尋找使用的內存,您需要添加名稱的長度並添加一些開銷。大約是導出變量的兩倍。 – Gilles 2011-09-04 23:53:15

2
${#VAR} 

告訴你的字符串VAR

17

這告訴你有多少個字符是在一個名爲「無功」的標量變量的值的長度:

echo ${#var} 

這告訴你在一個名爲「array」的數組中的元素數量:

echo ${#array[@]} 

這告訴你的字符數在數組中的元素:

echo ${#array[3]} 

如果你試圖得到一個數組的大小,你離開了[@]指數,你會得到元素0的長度:

$ array=(1 22 333 4444) 
$ echo ${#array} 
1 
$ echo ${#array[@]} 
4 
$ echo ${#array[2]} 
3 

如果你想要一個數組的所有元素的總長度,你可以迭代這個數組,並把它們加起來,你可以使用類似下面的IFS和一些步驟,或者你可以:

$ tmp="${array[*]}" 
$ echo $((${#tmp} - ${#array[@]} + 1)) 
10 

小心使用數組作爲自擊最後一個元素的索引元件的數量的支持稀疏數組:

$ array=(1 22 333 4444 55555) 
$ echo ${#array[@]} 
5 
$ array[9]=999999999 
$ echo ${#array[@]} 
6 
$ echo ${array[${#array[@]} - 1]} # same as echo ${array[6 - 1]} 

$ # only a newline is echoed since element 5 is empty (only if "nounset" option* is not set (default in most cases)) 
$ # when "nounset" option is set (possibly using command "set -u") then bash will print such error: 
$ # bash: array[${#array[@]} - 1]: unbound variable 
$ unset "array[1]" # always quote array elements when you unset them 
$ echo ${#array[@]} 
5 
$ echo ${array[${#array[@]} - 1]} # same as echo ${array[5 - 1]} 
55555 

這顯然不是最後一個元素。爲了得到最後一個元素:

$ echo ${array[@]: -1} # note the space before the minus sign 
999999999 

注意,在即將到來的Bash 4.2,你可以做echo ${array[-1]}獲得的最後一個元素。在4.2之前的版本中,對於否定下標,您會收到錯誤的下標錯誤。

要獲得最後一個元素的索引:

$ idx=(${!array[@]}) 
$ echo ${idx[@]: -1} 
9 

然後,你可以這樣做:

$ last=${idx[@]: -1} 
$ echo ${array[last]} 
999999999 

遍歷一個稀疏數組:

for idx in ${!array[@]} 
do 
    something_with ${array[idx]} 
done 

*我建議避免nounset

1

對於標量變量,${#VAR}給出了字符長度。在unibyte語言環境中,這是以字節爲單位的長度。以字節爲單位的大小是名稱的長度(以字節爲單位),再加上以字節爲單位的值的長度,加上常數開銷。

LC_ALL=C 
name=VAR 
size=$(($#name + $#VAR)) # plus a small overhead 

如果導出變量,則大小大致是兩倍。

LC_ALL=C 
name=VAR 
size=$((($#name + $#VAR) * 2)) # plus a small overhead 

對於數組變量,則需要的元素的總結的長度(再次,以字節爲單位),並添加每個元件的恆定的開銷加上用於陣列的恆定開銷。

LC_ALL=C 
name=VAR 
size=$(($#name)) # plus a small overhead 
for key in "${!VAR[@]}"; do 
    size=$((size + ${#key} + ${#VAR[$key]})) # plus a small overhead 
done 

這是一個最小測試函數,用於計算變量佔用的近似大小。考慮數組和輸出,但不包括$RANDOM等特殊的只讀變量。大小已在bash 4.2中觀察到,不同的版本可能會有不同的開銷。您可能需要根據系統類型和malloc實施來調整常量。

_sizeof_pointer=4 
_sizeof_int=4 
_malloc_granularity=16 
_malloc_overhead=16 
## Usage: compute_size VAR 
## Print the amount of memory (in bytes) used by VAR. 
## The extra bytes used by the memory allocator are not taken into account. 
add_size() { 
    local IFS="+" this extra 
    set $(($1 + _malloc_overhead)) 
    _size=$((_size + $1)) 
    set $(($1 % _malloc_granularity)) 
    [[ $1 -eq 0 ]] || _size=$((_size + _malloc_granularity - $1)) 
} 
compute_size() { 
    local LC_ALL=C _size=0 _key 
    if eval "[ -z \${$1+1} ]"; then echo 0; return; fi 
    add_size $((_sizeof_pointer*5 + _sizeof_int*2)) # constant overhead 
    add_size ${#1} # the name 
    case $(declare -p $1) in 
    declare\ -x*) 
     eval "add_size \${#$1}" # the value 
     eval "add_size \$((\${#1} + \${#$1} + 2))" # the export string 
     ;; 
    declare\ -a*) 
     eval 'for _key in "${!'$1'[@]}"; do 
       add_size $_key 
       add_size ${#'$1'[$_key]} 
       add_size $((_sizeof_pointer*4)) 
      done' 
     add_size $((_sizeof_pointer*2 + _sizeof_int*2)) 
     add_size $((_sizeof_pointer*4)) 
     ;; 
    *) 
     eval "add_size \${#$1}" # the value 
     ;; 
    esac 
    echo $_size 
} 
相關問題