我想在脚本中添加此awk命令,但始终出现错误。 我已放入"",但仍然出现错误。
system("awk -F"\t" '{ for ( i=1; i<=2; i++ ) { printf"%s\t", $i } printf"
"; }' myfile file2"};
错误是
String found where operator expected
at host_parse line 21, near"t" '{ for
( i=1; i<=2; i++ ) { printf""
Unquoted string"a" may clash with
future reserved word at myfile line
58.
Unquoted string"a" may clash with
future reserved word at myfile line
58.
syntax error at myfile line 21, near
"" awk -F"\"
谢谢。
您到底为什么要混合Awk和Perl? 它们具有相同的目的,因此,如果您有一个,则不需要另一个。
因为有时候正确的工具就是您已经知道如何使用的工具。
Yoy可以尝试使用此有用的工具将awk脚本转换为perl:a2p perldoc.perl.org/a2p.html
我不仅要对@larsmans进行评论,还想将其加粗,斜体并以H1样式显示!
@Axeman:不要忘记红色和闪烁。
@丹尼斯·威廉姆森::D
关于使用system命令的最棘手的部分之一是使用引号,该引号可以将正确的命令传递给操作系统。 Perl的q//构造对此非常有帮助:
# treat everything between the @...@ as uninterpolated string
system( q@awk -F"\t" '{ for ( i=1; i<=2; i++ ) { printf"%s\t", $i }
printf"
"; }' myfile file2@ );
将数组传递给系统甚至更好。 报价问题消失了。
为了回答您的紧迫问题,您需要跳过Perl system运算符的默认行为。通常,shell解析命令非常方便,但是如您所见,有时候,进行多级编码是很痛苦的,甚至是一个安全漏洞。
您可以使用system LIST和exec LIST形式完全忽略外壳程序的引用。根据您的情况,将代码更改为
#! /usr/bin/env perl
use strict;
use warnings;
my @cmd = (
"awk",
"-F","\t",
'{ for ( i=1; i<=2; i++ ) {
printf"%s\t", $i
}
printf"
";
}',
"myfile","file2",
);
system(@cmd) == 0 or warn"$0: awk exited" . ($? >> 8);
您不必使用临时数组,但我不喜欢带有多行命令和成功检查结果的代码。
给定myfile包含
1 2 3 4
foo bar baz
oui oui monsieur
和file2与
a b c
d e f g
(两种情况下的分隔符均为TAB字符),则输出为
1 2
foo bar
oui oui
a b
d e
它们是不可见的,但是上面输出的每一行都有一个尾随的TAB。
在Perl中执行相同的操作非常简单。例如,
sub print_first_two_columns {
foreach my $path (@_) {
open my $fh,"
while () {
chomp;
my(@cols) = (split /\t/)[0 .. 1];
print join("\t", @cols),"
";
}
close $fh;
}
}
可能不明显的部分是从split返回的值的一部分,但是发生的事情在概念上很简单。切片使您可以在多个索引处获取数据(在这种情况下为0和1,即第一和第二列)。范围运算符表达式0 .. 1的结果为列表0和1。如果稍后决定要使用前四列,则将其更改为0 .. 3。
调用上面的子
print_first_two_columns"myfile","file2";
请注意,代码并不完全等效:它不会保留结尾的TAB字符。
在命令行中,它甚至更简单:
$ perl -lane '$,="\t"; print @F[0,1]' myfile file2
1 2
foo bar
oui oui
a b
d e
您不需要外壳程序来解释任何重定向(或其他外壳程序设施),因此最好将参数列表传递给system()
system 'awk', '-F',"\t",
'{for (i=1; i<=2; i++) {printf"%s\t", $i}; print""}',
'myfile', 'file2';