我有以下UNIX语句:
#!/bin/bash
$x=$((grep ^'[a-z]' $1 | wc -l))
echo "$x"
但是,每当我尝试运行脚本时,我都会收到与缺少操作数有关的错误消息。有没有办法在UNIX中为变量赋值这样的值?
编辑:
嗯,我很清楚,grep似乎无法检查单个单词,这是我原本打算做的。是否有一个UNIX命令,任何人都可以指向我处理搜索单词中的模式?我正在尝试制作一些unix代码,可以判断传递给脚本的单词是否以数字开头。什么UNIX调用最有帮助?
答案 0 :(得分:4)
我相信你剩下的问题是$( ... )
和$(( ... ))
是两个非常不同的东西。前者确实命令替换,这是你想要的。后者做算术。试试这个:
#! /bin/sh
x=$(grep -c '^[a-z]' "$1")
echo "$x"
我也不知道你为什么在单引号之外有插入符号;这可能会导致一些shell的问题(插入符号要么是历史扩展,要么是|的别名),我认为bash不是那些shell之一,但是没有理由诱惑命运。
强制性切向建议:扩展shell变量时,总是将它们放在双引号内,除非你特别需要进行单词拆分。 (这就是我将$1
更改为"$1"
的原因。如果没有更改,如果您为其提供了名称中包含空格的文件,您的脚本就会中断。)
编辑:现在您说您想知道传递给脚本的单词是否以数字开头。通过“传递给脚本”,我将假设你的意思是这样的:
./script WORD
最简单的方法是不涉及grep
或命令替换:
#! /bin/sh
case "$1" in
[0-9]*)
echo "Starts with a number"
;;
*)
echo "Doesn't start with a number"
;;
esac
是的,“case”语法与shell中的其他内容完全不同;如果你想要一种内部一致的语言,Python就等着你thataway。你在每个开放式之前放置的模式都是globs,而不是regex。如果你需要一个正则表达式,你必须做一些更复杂的事情,例如
#! /bin/sh
if [ $(expr "$1" : '[0-9]\{3,5\}x') -gt 0 ]; then
echo "Starts with a three-to-five digit number followed by an x"
fi
有人说没有必要在case
和in
之间的变量扩展周围加上引号。它们在技术上是正确的,但无论如何都应该被忽略,因为这是一个太多的疣要记住。其他人说你可以在每个glob之前放一个开括号,然后你的编辑就不会对不匹配的括号产生脾气暴躁。我赞成编辑非脾气暴躁,但我不知道变异是多么便携。
答案 1 :(得分:1)
您没有将$
放在正在分配的变量前面:
> $x=$(echo -en "1\n2\n3" | grep 3)
bash: =3: command not found
> x=$(echo -en "1\n2\n3" | grep 3)
> echo $x
3
当你在$x
之前写$x
时,它似乎被扩展为空;这就是为什么第一行被完全评估为=3
。
答案 2 :(得分:1)
Zack使用case
有正确的方法。 bash有更多的模式匹配运算符:
shopt -s extglob
var="foobar"
if [[ "$var" == @([a-z]*) ]]; then
echo "var starts with a letter"
fi
在bash手册页中,阅读“复合命令”下的[[
和“模式匹配”部分。
答案 3 :(得分:0)
而不是wc
,您可以使用grep -c
。
答案 4 :(得分:0)
这应该可行
#!/bin/bash
x=$(grep ^'[a-z]' $1 | wc -l)
echo "$x"
请注意,在分配变量时不需要$,也不需要extra()。
答案 5 :(得分:0)
x=$(grep '^[a-z]' "$1" | wc -l)
或只是一个awk命令
x=$(awk '/^[a-z]/{c++}END{print c}')