проблема в использовании awk

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