#shell #awk
#оболочка #awk
Вопрос:
я не смог это решить. когда я запускаю эту программу, я получаю следующую ошибку «строка 7: неожиданный EOF при поиске соответствия `’ «
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
}
fi
Обновление: из другого, недавно закрытого вопроса
Чтобы быть более конкретным, это код моего проекта
if [ "$FORMAT" = "java" ]; then
cat $INPUT_FILE | awk -F":" '
/^$/ { print "" }
/^//.*/ { print " "$0}
/:string:/ { print " public static final String "$1" = "$3";" }
/:char:/ { print " public static final char "$1" = "$3";" }
/:ullong:/ { print " public static final long "$1" = "$3";" }
/:ulong:/ { print " public static final int "$1" = "$3";" }
/:long:/ { print " public static final int "$1" = "$3";" }
' >> $CONST_FILE
fi;
Теперь мне нужно сократить $ 3 (это значение фактически считывается из другого файла) на две части (только для ulong). допустим
$3=1256985361455ULL
мне нужно выполнить усечение до 1256985361455 и ULL. (только когда оно длинное)
пожалуйста, помогите мне в этом вопросе.
я попытался использовать другой awk внутри следующего, но оказался в хаосе.
/:ullong:/ { print " public static final long "$1" = "$3";" }
Комментарии:
1. Что вы пытаетесь сделать? Приведенный выше фрагмент имеет мало смысла.
2. мне нужно сначала усечь вхождение ‘U’, а затем из выходных данных этой первой команды awk мне нужно o усечь вхождение ‘a’. я просто пытаюсь привести это в качестве примера, потому что мне нужно использовать аналогичный метод в моем проекте
3. Итак, каков ваш конечный результат после «усечения»? Вы имеете в виду удаление всех «a» и «U»? Пожалуйста, четко задайте свой вопрос, предоставив примеры вывода, которые вы хотите, где это необходимо.
4. Используйте несколько каналов — смотрите пример в моем ответе
5. В теле вашего скрипта awk нет необходимости помещать символ продолжения () в конце каждой строки.
Ответ №1:
Если вы ожидаете, что значение в 3 доллара для записей ulong будет примерно таким «1256985361455ULL», тогда
/:ullong:/ {
sub(/ULL$/, "", $3)
print " public static final long "$1" = "$3";"
}
Комментарии:
1. @Logeshwari, теперь пришло время принять некоторые ответы на ваши вопросы.
Ответ №2:
Ваша проблема с кавычками заключается в том, что, как только вы запускаете команду, заключенную в обратные кавычки, это продолжается до следующей обратной кавычки. Это ваш код, как показано выше, за исключением того, что я удалил пустые строки.
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
}
fi
(Обратные кавычки ‘ `
‘ трудно отобразить во встроенной уценке.)
В строке var1=
начинается выражение, заключенное в обратные кавычки, которое останавливается на следующей неэкранированной обратной кавычке, которая находится после var2=
. Затем он считывает оставшуюся часть этой строки и в следующей строке встречает одинарную кавычку. Когда она ищет следующую одинарную кавычку, ее нет — поэтому она сообщает об ошибке. Вы можете продемонстрировать, что это происходит поэтапно:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
}
fi
В приведенном выше скрипте перед обратной кавычкой после var2=
есть экранирующая черта (обратная косая черта), так что теперь команда в обратных кавычках распространяется на обратную кавычку после print
строки. Это по-прежнему недопустимая оболочка; строка с }
объединяется с fi
для создания имени команды }fi
, поэтому вы по-прежнему получаете неожиданную ошибку EOF — потому что fi
для конца if
отсутствует. Измените скрипт еще раз:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
#}
fi
Это закомментирует закрывающую фигурную скобку, и сценарий оболочки теперь «действителен»; теперь awk
очередь начать жаловаться на недопустимый сценарий, который ему предоставлен.
awk -FU '{
var2=`echo $var1 | awk -F"a"
{print " "$2}'
awk: syntax error at source line 2
context is
>>> var2=` <<<
awk: illegal statement at source line 2
awk: illegal statement at source line 2
missing }
Другие люди дали вам примерно то, что вам нужно в качестве ответа. Я бы, вероятно, использовал Perl для разделения (и я подозреваю, что мог бы потерять промежуточный массив @x
, если бы потратил на это достаточно времени, создавая скрипт с линейным шумом):
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]
then var1=$(echo $a | perl -ne '@x=split /[aU]/; print "$x[1]n"')
fi
Однако вы также можете сделать это в одной строке с awk
, таким образом:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]
then var1=$(echo $a | awk -Fa '{sub("ULL","",$2); print $2}')
fi
Это разбивает входные данные на ‘a’ вместо ‘U’; затем он удаляет ‘ULL’ из второго поля и печатает его. Если вы хотите разделить на ‘U’, то вы используете:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]
then var1=$(echo $a | awk -FU '{sub("[0-9] a", "", $1); print $1}')
fi
Регулярное выражение в sub
таким образом, немного сложнее.
Ответ №3:
Не уверен, что именно вы пытаетесь сделать, но эта небольшая перезапись распечатала среднюю часть a (я думаю, это то, что вы хотели)
> cat moo.sh
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '{print $1}'`
var2=`echo $var1 | awk -F"a" '{print " "$2}'`
echo $var2
fi
> sh moo.sh
1504606846976
Ответ №4:
Вы не можете выполнять команды оболочки внутри awk
, за исключением системных вызовов. без того, чтобы вы сказали нам, чего вы пытаетесь достичь
#!/bin/bash
a=115292a1504606846976ULL
b=2
case "$b" in
2 )
a=${a%U*}
echo ${a#*a} # I assume you want to get 1504606846976
esac
Ответ №5:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F "U" '{print $1}' | awk -F "a" '{print $2}'`
fi
Комментарии:
1. Если
awk
необходимо использовать, нет необходимости вызывать 2 ее экземпляра. вы можете либо выполнитьsub/gsub/split
включение$1
в первомawk
, либо использовать-F"[Ua]"
2. @kurumi: Нет, но это иллюстрирует, как сделать то, что ему нужно, доступным для чтения способом, используя только то, что OP демонстрирует понимание.
sed
в любом случае было бы лучшим выбором для этого IMO.