簡體   English   中英

在 bash 中,如何計算變量中的行數?

[英]In bash, how do I count the number of lines in a variable?

我有一個變量,其中存儲了一個字符串,需要檢查它是否有行:

var=`ls "$sdir" | grep "$input"`

偽代碼:

while [ ! $var's number of lines -eq 1 ]
  do something

這就是我對如何檢查它的想法。 echo $var | wc -l echo $var | wc -l不起作用-它總是說1 ,即使它有3

echo -e也不起作用。

行情很重要。

echo "$var" | wc -l

對於空變量(未定義或空字符串),此處發布的已接受答案和其他答案不起作用。

這有效:

echo -n "$VARIABLE" | grep -c '^'

例如:

ZERO=
ONE="just one line"
TWO="first
> second"

echo -n "$ZERO" | grep -c '^'
0
echo -n "$ONE" | grep -c '^'
1
echo -n "$TWO" | grep -c '^'
2

在 bash 中使用此處字符串的另一種方法:

wc -l <<< "$var"

本評論所述,空的$var將導致 1 行而不是 0 行,因為在這種情況下,字符串會添加換行符( 說明)。

沒有人提到參數擴展,所以這里有兩種使用純bash的方法。

方法一

刪除非換行符,然后得到字符串長度 + 1。引號很重要

 var="${var//[!$'\n']/}"
 echo $((${#var} + 1))

方法二

轉換為數組,然后獲取數組長度。 為此,請不要使用引號

 set -f # disable glob (wildcard) expansion
 IFS=$'\n' # let's make sure we split on newline chars
 var=(${var})
 echo ${#var[@]}

@Julian 的答案的一個更簡單的版本,適用於所有字符串,有或沒有尾隨 \n (它確實將只包含一個尾隨 \n 的文件計算為空):

printf "%s" "$a" | grep -c "^"

  • 返回零:未設置的變量、空字符串、包含裸換行符的字符串
  • 返回 1:任何非空行,帶或不帶尾隨換行符
  • ETC

Output:

# a=
# printf "%s" "$a" | grep -c "^"
0

# a=""
# printf "%s" "$a" | grep -c "^"
0

# a="$(printf "")"
# printf "%s" "$a" | grep -c "^"
0

# a="$(printf "\n")"
# printf "%s" "$a" | grep -c "^"
0

# a="$(printf " \n")"
# printf "%s" "$a" | grep -c "^"
1

# a="$(printf " ")"
# printf "%s" "$a" | grep -c "^"
1

# a="aaa"
# printf "%s" "$a" | grep -c "^"
1

# a="$(printf "%s" "aaa")"
# printf "%s" "$a" | grep -c "^"
1

# a="$(printf "%s\n" "aaa")"
# printf "%s" "$a" | grep -c "^"
1

# a="$(printf "%s\n%s" "aaa" "bbb")"
# printf "%s" "$a" | grep -c "^"
2

# a="$(printf "%s\n%s\n" "aaa" "bbb")"
# printf "%s" "$a" | grep -c "^"
2

您可以將“wc -l”替換為“wc -w”來計算字數而不是行數。 這不會計算任何新行,並且可用於在您繼續之前測試您的原始結果是否為空。

如果 grep 未返回任何結果,則投票最多的答案將失敗。

Homer Simpson
Marge Simpson
Bart Simpson
Lisa Simpson
Ned Flanders
Rod Flanders
Todd Flanders
Moe Szyslak

這是錯誤的做法

wiggums=$(grep -iF "Wiggum" characters.txt);
num_wiggums=$(echo "$wiggums" | wc -l);
echo "There are ${num_wiggums} here!";

那里會告訴我們,列表中有1 Wiggum ,即使沒有。

相反,您需要進行一項額外檢查以查看變量是否為空( -z ,如“為零”)。 如果 grep 沒有返回任何內容,則該變量將為空。

matches=$(grep -iF "VanHouten" characters.txt);

if [ -z "$matches" ]; then
    num_matches=0;
else
    num_matches=$(echo "$matches" | wc -l);
fi

echo "There are ${num_matches} VanHoutens on the list";

另一種計算變量中行數的方法 - 假設您確實檢查了它是否已成功填充或它不為空,那么只需檢查 $? var subshell 結果做作之后-:

readarray -t tab <<<"${var}"
echo ${#tab[@]}

readarray|mapfile是 bash 內部命令,它將輸入文件或在這種情況下的字符串轉換為基於換行符的數組。

-t標志防止在數組單元格的末尾存儲換行符,這對於以后使用存儲的值很有用

這種方法的優點是:

  • 沒有外部命令 (wc, grep, ...)
  • 沒有子殼(管道)
  • 沒有 IFS 問題(修改后恢復,在內部命令上使用受命令限制的 scope 很棘手,...)

為了避免“wc -l”命令中的文件名:

lines=$(< "$filename" wc -l)
echo "$lines"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM