麻烦在UNIX中嵌套表达式

时间:2010-10-08 01:54:50

标签: bash unix scripting shell

我有以下UNIX语句:

#!/bin/bash
$x=$((grep ^'[a-z]' $1 | wc -l))
echo "$x"

但是,每当我尝试运行脚本时,我都会收到与缺少操作数有关的错误消息。有没有办法在UNIX中为变量赋值这样的值?

编辑:

嗯,我很清楚,grep似乎无法检查单个单词,这是我原本打算做的。是否有一个UNIX命令,任何人都可以指向我处理搜索单词中的模式?我正在尝试制作一些unix代码,可以判断传递给脚本的单词是否以数字开头。什么UNIX调用最有帮助?

6 个答案:

答案 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

有人说没有必要在casein之间的变量扩展周围加上引号。它们在技术上是正确的,但无论如何都应该被忽略,因为这是一个太多的疣要记住。其他人说你可以在每个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}')