使用awk的问题

时间:2011-04-19 12:27:36

标签: shell 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(这个值实际上是从另一个文件中读取)分为两部分(仅适用于ullong)。让我们说

$3=1256985361455ULL

我需要截断到1256985361455和ULL。 (只有当它是ullong) 请帮我解决这个问题。

我尝试在下面使用另一个awk,但最终陷入了混乱。

/:ullong:/ { print "    public static final long "$1" = "$3";" }\

5 个答案:

答案 0 :(得分:2)

您的引用问题是因为一旦您启动了后引用命令,它将一直持续到下一个反引号。这是你的代码,如上所示,除了我删除了空行。

a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '\
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
}\
fi

后退引号'`'很难在内联Markdown中显示。

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行之后的反引号。这仍然是无效的shell; }\fi组合的行与命名}fi结合,因此您仍然会收到意外的EOF错误 - 因为fiif的结尾1}}丢失了。再次修改脚本:

a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '\
{
var2=\`echo $var1 | awk -F"a"
{print " "$2}'`
#}\
fi

这注释了close括号,shell脚本现在是'有效';它已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中的正则表达式稍微复杂一些。

答案 1 :(得分:2)

如果您希望ullong记录的$ 3值类似于“1256985361455ULL”那么

/:ullong:/ { 
    sub(/ULL$/, "", $3)
    print "    public static final long "$1" = "$3";" 
}

答案 2 :(得分:1)

不确定你想要做什么,但这个轻微的重写打印出来的中间部分(这就是我想你想要的)

> 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

答案 3 :(得分:0)

除了进行系统调用之外,你不能在awk内执行shell命令。没有你告诉我们你想要实现的目标

#!/bin/bash
a=115292a1504606846976ULL
b=2
case "$b" in
 2 ) 
    a=${a%U*}
    echo ${a#*a} # I assume you want to get 1504606846976
esac

答案 4 :(得分:0)

a=115292a1504606846976ULL
b=2

if [ "$b" = "2" ]; then
  var1=`echo $a | awk -F "U" '{print $1}' | awk -F "a" '{print $2}'`
fi