我有一个变量,其中存储了一个字符串,需要检查它是否包含行:
var=`ls "$sdir" | grep "$input"`
伪代码:
while [ ! $var's number of lines -eq 1 ]
do something
那是我关于如何检查的想法。echo $var | wc -l
不起作用-1
即使可以,它总是说3
。
echo -e
效果不佳。
Answers:
行情很重要。
echo "$var" | wc -l
if [ -z "$var" ]; then printf '%s\n' '0'; else printf '%s\n' "${var%$'\n'}" | wc -l; fi
。尝试使用var=
(无行)var='foo'
和var=$'foo\n'
(在* nix意义上都行)。
LINE_COUNT=$(wc -l <<< "${var}")
echo -n
只会将计数减少一。@lucifuriousecho $(wc -l <<< "${NONEXISTENTVAR}")
仍然给出1,而不是0
如果变量为空(未定义或字符串为空),则此处接受的答案和其他答案将不起作用。
这有效:
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
WHITESPACE_ONE=' '
在我的shell(bash)中仍然可以正常工作,正确报告了一行。
printf
而不是进行简化echo -n
。我已将此添加为替代答案,以包括测试结果。见下文。
您可以将“ wc -l”替换为“ wc -w”,以计算单词数而不是行数。这不会计算任何新行,可用于在继续之前测试原始结果是否为空。
wc -l
即使输入变量为空,解决方案也会输出1,因此使用起来wc -w
会更好。
没有人提到参数扩展,因此这里有几种使用纯bash的方法。
方法1
删除非换行符,然后获取字符串长度+1。引号很重要。
var="${var//[!$'\n']/}"
echo $((${#var} + 1))
方法2
转换为数组,然后获取数组长度。为此,请不要使用引号。
set -f # disable glob (wildcard) expansion
IFS=$'\n' # let's make sure we split on newline chars
var=(${var})
echo ${#var[@]}
IFS
。因此IFS=$'\n'
,请确保将变量扩展为数组时将其拆分为新行:IFS=$'\n'; var=(${var})
set -f
需要避免不必要的全局扩展。尝试在上使用方法2 var=$'*\n.*'
。
@Julian答案的简单版本,适用于所有带有或不带有尾随\ n的字符串(它会将仅包含一个尾随\ n的文件计为空):
printf "%s" "$a" | grep -c "^"
输出:
# 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
echo
(例如echo -n
)不是标准的,并且在不同的实现上可能会给出不同的结果。而printf
默认情况下我们想要什么。另外,使用printf
可以节省您一个过程,因为它是内置的Shell。(建议:printf "$a" | wc -l
更简洁,避免不必要的使用grep
)
printf .... | wc -l
只会删除一条额外的行(换行符),因此在空行的情况下,结果将为0。正确。但是,如果我们通过2线,其结果将是1,其中传递给同一个变量printf ... | grep "^"
将正确地返回2.此外,直接使用printf "$a"
是很危险的,因为它会导致无记载错误如果字符串包含意外字符一样%s
,%d
所以on ...如果字符串以短划线开头,则相同。相反,输入2中的参数printf
会自动转义
如果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";