Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么双引号在awk脚本中cmd内的echo语句中不起作用?_Awk_Base64 - Fatal编程技术网

为什么双引号在awk脚本中cmd内的echo语句中不起作用?

为什么双引号在awk脚本中cmd内的echo语句中不起作用?,awk,base64,Awk,Base64,输入: gawk 'BEGIN { FS="|"; OFS="|" }NR ==1 {print} NR >=2 {cmd1="echo -n "$2" | base64 -w 0";cmd1 | getline d1;close(cmd1); print $1,d1 }' dummy2.txt 预期产出: id|dummy

输入:

gawk 'BEGIN { FS="|"; OFS="|" }NR ==1 {print} NR >=2 {cmd1="echo -n "$2" | base64 -w 0";cmd1 | getline d1;close(cmd1); print $1,d1 }' dummy2.txt
预期产出:

id|dummy                                                                           
1|subhashree:1;user=phn                                                             
2|subha:2;user=phn        

                                                                                                            
由脚本生成的输出:

id|dummy                                       
1|c3ViaGFzaHJlZToxO3VzZXI9cGhuCg==                               
2|c3ViaGE6Mjt1c2VyPXBobgo= 

                                           
据我所知,2美元左右的双报价是问题的根源。它不工作,因此没有正确地编码字符串,只是在分号后去掉字符串。因为它在分号内工作,并在终端中给出正确的输出

id|dummy                                       
1|subhashree:1                                                                                                                                                                                                                                                                                                                                                   
2|subha:2     

                                                                                                   
我已经尝试了不同的变化与单双报价内awk,但它不工作。任何帮助将高度感谢

提前非常感谢。

您现有的cmd1

echo "subhashree:1;user=phn" | base64                                               
c3ViaGFzaHJlZToxO3VzZXI9cGhuCg==                                                         
[root@DERATVIV04 encode]# echo "subha:2;user=phn" | base64                               
c3ViaGE6Mjt1c2VyPXBobgo=        

                                                      
所以,如果你执行下面的命令,就会产生

echo -n subhashree:1;user=phn | base64 -w 0

                    ^ semicolon is there
引用

$ echo -n subhashree:1;user=phn | base64 -w 0
subhashree:1
解决方案就是在echo-n | base64-w0之前使用引号

它可以简化如下

$ cat file 
id|dummy
1|subhashree:1;user=phn
2|subha:2;user=phn

$ gawk -v q="'" 'BEGIN { FS="|"; OFS="|" }NR ==1 {print} NR >=2 {cmd1="echo -n " q $2 q" | base64 -w 0";  cmd1 | getline d1;close(cmd1); print $1,d1 }' file
id|dummy
1|c3ViaGFzaHJlZToxO3VzZXI9cGhu
2|c3ViaGE6Mjt1c2VyPXBobg==
根据建议

您现有的cmd1正在生成

echo "subhashree:1;user=phn" | base64                                               
c3ViaGFzaHJlZToxO3VzZXI9cGhuCg==                                                         
[root@DERATVIV04 encode]# echo "subha:2;user=phn" | base64                               
c3ViaGE6Mjt1c2VyPXBobgo=        

                                                      
所以,如果你执行下面的命令,就会产生

echo -n subhashree:1;user=phn | base64 -w 0

                    ^ semicolon is there
引用

$ echo -n subhashree:1;user=phn | base64 -w 0
subhashree:1
解决方案就是在echo-n | base64-w0之前使用引号

它可以简化如下

$ cat file 
id|dummy
1|subhashree:1;user=phn
2|subha:2;user=phn

$ gawk -v q="'" 'BEGIN { FS="|"; OFS="|" }NR ==1 {print} NR >=2 {cmd1="echo -n " q $2 q" | base64 -w 0";  cmd1 | getline d1;close(cmd1); print $1,d1 }' file
id|dummy
1|c3ViaGFzaHJlZToxO3VzZXI9cGhu
2|c3ViaGE6Mjt1c2VyPXBobg==
根据建议


问题是在shell上下文中尝试运行echo命令时缺少引号。你要做的基本上是转化成

if/while ( (getline var < file) > 0)
if/while ( (command | getline var) > 0)
if/while ( (command |& getline var) > 0)
shell已将其作为两个命令执行,两个命令之间用分隔符分隔;i、 e.user=phn | base64-w 0表示一个赋值后接一个管道,该管道将为空,因为赋值不会产生任何超过base64编码标准输入的结果。另一段subhashree:1刚刚被回显,它存储在getline变量d1中

解决问题的正确方法应该是使用引号

echo -n subhashree:1;user=phn | base64 -w 0
当你说,你使用了$2的引号,这实际上是不对的,引号实际上是在awk的上下文中用来连接cmd字符串的,即echo-n、$2和| base64-w 0只是连接在一起。建议的双引号需要放在shell的上下文中

因此,有了这些和其他一些修复,您的awk命令应该在下面。添加了gsub以删除显示的输入中存在的尾随空格。也使用了printfoverecho

echo -n "subhashree:1;user=phn" | base64 -w 0
因此,使用上面的命令,您的命令将按如下方式执行,这将产生正确的结果

awk -v FS="|" '
    BEGIN {
        OFS = FS
    }
    
    NR == 1 {
        print
    }
    
    NR >= 2 {
        gsub(/[[:space:]]+/, "", $2)
        cmd = "printf \"%s\" \"" $2 "\" | base64 -w 0"
        if ((cmd | getline result) > 0) {
            $2 = result
        }
        close(cmd)
        print
    }    
' file

问题是在shell上下文中尝试运行echo命令时缺少引号。你要做的基本上是转化成

if/while ( (getline var < file) > 0)
if/while ( (command | getline var) > 0)
if/while ( (command |& getline var) > 0)
shell已将其作为两个命令执行,两个命令之间用分隔符分隔;i、 e.user=phn | base64-w 0表示一个赋值后接一个管道,该管道将为空,因为赋值不会产生任何超过base64编码标准输入的结果。另一段subhashree:1刚刚被回显,它存储在getline变量d1中

解决问题的正确方法应该是使用引号

echo -n subhashree:1;user=phn | base64 -w 0
当你说,你使用了$2的引号,这实际上是不对的,引号实际上是在awk的上下文中用来连接cmd字符串的,即echo-n、$2和| base64-w 0只是连接在一起。建议的双引号需要放在shell的上下文中

因此,有了这些和其他一些修复,您的awk命令应该在下面。添加了gsub以删除显示的输入中存在的尾随空格。也使用了printfoverecho

echo -n "subhashree:1;user=phn" | base64 -w 0
因此,使用上面的命令,您的命令将按如下方式执行,这将产生正确的结果

awk -v FS="|" '
    BEGIN {
        OFS = FS
    }
    
    NR == 1 {
        print
    }
    
    NR >= 2 {
        gsub(/[[:space:]]+/, "", $2)
        cmd = "printf \"%s\" \"" $2 "\" | base64 -w 0"
        if ((cmd | getline result) > 0) {
            $2 = result
        }
        close(cmd)
        print
    }    
' file

<>你已经得到了解释如何使用AWK的答案,但是你也应该考虑不使用AWK来解决这个问题。对其他命令(如bas64)的调用进行排序的工具是shell,而不是awk。在通话方面,您要做的是:

printf "%s" "subhashree:1;user=phn" | base64 -w 0
然而,如果您直接从shell调用base64,它将是:

shell { awk { loop_on_input { shell { base64 } } } }
注意,awk命令在每行输入中生成一个新的子shell,而shell的直接调用则不是

例如:

shell { loop_on_input { base64 } }
上面的时间是通过运行此命令生成的,在answers中发布的两个awk脚本的时间大致相同,所以我只是随机选择了一个:

$ ./tst.sh file100
Awk:

real    0m23.247s
user    0m3.755s
sys     0m10.966s

Shell:

real    0m14.512s
user    0m1.530s
sys     0m4.776s

<>你已经得到了解释如何使用AWK的答案,但是你也应该考虑不使用AWK来解决这个问题。对其他命令(如bas64)的调用进行排序的工具是shell,而不是awk。在通话方面,您要做的是:

printf "%s" "subhashree:1;user=phn" | base64 -w 0
然而,如果您直接从shell调用base64,它将是:

shell { awk { loop_on_input { shell { base64 } } } }
注意,awk命令在每行输入中生成一个新的子shell,而shell的直接调用则不是

例如:

shell { loop_on_input { base64 } }
上面的时间是通过运行此命令生成的,在answers中发布的两个awk脚本的时间大致相同,所以我只是随机选择了一个:

$ ./tst.sh file100
Awk:

real    0m23.247s
user    0m3.755s
sys     0m10.966s

Shell:

real    0m14.512s
user    0m1.530s
sys     0m4.776s

很好-对于调用getline和使用它的结果来说,语法完全正确。很好-对于调用getline和使用它的结果来说,语法完全正确。嗨,Ed Morton…我完全理解你的观点,我也有一个bash的解决方案,但重点是我需要在我的用例中使用awk,因为我需要使用其他awk的输出此base64用例的命令…因此我完成了所有
awk as I hv中的解决方案可以处理CSV文件的多个列以执行不同的操作…但是非常感谢您的解释,它非常有用…肯定会尝试一下,如果我被允许…@SubhashreeBehera不,您不必在awk中执行此操作,您可以简单地将此输出管道到awk,反之亦然。如果您不关心效率,那么从awk for调用1字段的外部命令是可以的,不过只要语法正确,这两个awk答案现在都可以。嗨,Ed Morton…我完全理解您的观点,我也有一个bash的解决方案,但重点是我需要在我的用例中使用awk,因为我需要使用将其他awk命令输出到此base64用例…因此,我在awk中完成了所有解决方案,因为我在处理CSV文件的多列以执行不同的操作…但非常感谢您的解释,它确实非常有用…如果我被允许,我一定会尝试…@SubhashreeBehera不,您不必在awk中执行此操作,您可以简单地通过管道将此输出传输到awk,反之亦然。如果您不关心效率,那么从awk for为1字段调用外部命令是可以的,但前提是您获得了两个awk答案现在所使用的语法正确。使用一个变量来保存单引号并不坏,但它只在进行字符串连接的上下文中起作用,因此最好在任何地方使用\047“需要”,因为它在所有上下文中都有效$0==\047foo\047,/\047foo\047/,等等。无论脚本是在命令行上调用还是存储在文件中,它都可以工作,不像“\的其他常见选项,并且不需要您记住在命令行上写入-v q=”。因此md1=echo-n q$2 q | base64-w 0可以写为md1=echo-n\047$2\047 | base64-w 0,然后您可以去掉-v q=”。使用变量保留单引号并不坏,但它仅在进行字符串连接的上下文中有效,因此,在需要的任何地方使用\047都会更好,因为它在所有上下文中都有效$0==\047foo\047,/\047foo\047/,因此,md1=echo-nq$2q | base64-w0可以写成md1=echo-n\047$2\047 | base64-w0,然后就可以去掉-vq=”。