Выражение вложенности выражений в UNIX - PullRequest
1 голос
/ 08 октября 2010

У меня есть следующий оператор UNIX:

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

Однако я получаю сообщение об ошибке, касающееся отсутствующего операнда, всякий раз, когда я пытаюсь запустить скрипт. Есть ли способ присвоить переменной значение, как в UNIX?

EDIT:

Что ж, мне стало ясно, что grep не может рассматривать отдельные слова, что я и собирался сделать. Есть ли команда UNIX, на которую кто-нибудь может указать мне, которая занимается поиском шаблона в слове? Я пытаюсь сделать какой-нибудь код Unix, который может сказать, начинается ли слово, переданное в скрипт, с цифры. Какой вызов UNIX будет наиболее полезным?

Ответы [ 6 ]

4 голосов
/ 08 октября 2010

Я полагаю, что ваша остающаяся проблема в том, что $( ... ) и $(( ... )) - это две совершенно разные вещи.Первый из них выполняет подстановку команд, что вам и нужно.Последний делает арифметику .Попробуйте это:

#! /bin/sh

x=$(grep -c '^[a-z]' "$1")
echo "$x"

Я также не знаю, почему у вас была каретка за пределами одинарных кавычек;это может вызвать проблемы с некоторыми оболочками (где символ caret либо расширяет историю, либо является псевдонимом для |), я думаю, что bash не является одной из таких оболочек, но нет причин искушать судьбу.расширяя переменные оболочки, ВСЕГДА помещайте их в двойные кавычки, если только вам не требуется разделение слов.(Вот почему я изменил $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" безвозмездно отличается от всего остального в оболочке;если вам нужен внутренне согласованный язык, Python ждет вас thataway .Шаблоны, которые вы помещаете перед каждым открытым пареном - это глобусы, а не регулярные выражения.Если вам нужно регулярное выражение, вы должны сделать что-то более сложное, например,

#! /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.Они технически правильны, но все равно их следует игнорировать, потому что это слишком много бородавок, чтобы помнить.Другие люди говорят, что вы можете ставить открытые скобки перед каждым глобусом, и тогда ваш редактор не будет раздражен по поводу несоответствующих скобок.Я одобряю отсутствие раздражительности редактора, но я не знаю, насколько это вариативно.

1 голос
/ 08 октября 2010

Зак имеет правильный подход, используя case.bash имеет больше операторов сопоставления с образцом:

shopt -s extglob

var="foobar"
if [[ "$var" == @([a-z]*) ]]; then
    echo "var starts with a letter"
fi

На странице руководства bash прочитайте о [[ в разделе «Составные команды» и в разделе «Сопоставление с образцом».

1 голос
/ 08 октября 2010

Вы не ставите $ перед назначаемой переменной:

> $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.

0 голосов
/ 08 октября 2010
x=$(grep '^[a-z]' "$1" | wc -l)

или только одна команда awk

x=$(awk '/^[a-z]/{c++}END{print c}')
0 голосов
/ 08 октября 2010

Это должно работать нормально

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

Обратите внимание, что $ не требуется при присваивании переменным, и extra () также не требуется.

0 голосов
/ 08 октября 2010

Вместо wc вы можете использовать grep -c.

...