Linux 如何为处理的每一行向AWK内的命令传递参数
我想将参数$8(文件名)传递给函数“testfunc”。函数应该grep该文件中的一个关键字并返回一年。问题是Linux命令“grep”在fileN中看不到任何内容。如果我直接通过8美元,它仍然看不到任何东西Linux 如何为处理的每一行向AWK内的命令传递参数,linux,parameters,awk,command,gawk,Linux,Parameters,Awk,Command,Gawk,我想将参数$8(文件名)传递给函数“testfunc”。函数应该grep该文件中的一个关键字并返回一年。问题是Linux命令“grep”在fileN中看不到任何内容。如果我直接通过8美元,它仍然看不到任何东西 awk ' function testfunc(fileN, my_year) { "grep 'key_word' fileN" | getline my_year return(my_year) close("grep 'key_word'
awk '
function testfunc(fileN, my_year)
{ "grep 'key_word' fileN" | getline my_year
return(my_year)
close("grep 'key_word' fileN")
}
BEGIN {OFS="\t"}
{printf "%s\t%s\t%s\t", $8, testfunc($8), $9}'
试试这个:
function testfunc(fileN)
{
cmd="grep 'key_word' " fileN
cmd | getline my_year
return(sprintf("%s",my_year))
}
这是您要查找的语法:
awk '
function testfunc(fileN, my_year, cmd)
{ cmd = "grep \"key_word\" " fileN
cmd | getline my_year
close(cmd)
return(my_year)
}
BEGIN {OFS="\t"}
{printf "%s\t%s\t%s\t", $8, testfunc($8), $9}'
但正如我在评论中提到的——不要这样做,无论你想做什么,这都是错误的方法
请注意,不能在单引号分隔的脚本中使用单引号
编辑:让我试着澄清我关于使用不同方法的观点。您似乎有一个文件,让我们称它为“file1”,在它的第8个字段中有另一个文件名,在它的第9个字段中有一些您关心的其他值。在第8个字段中命名的所有文件都包含一行,其中包含文本“关键字”,您要打印的是文件1中的第8个字段,然后是选项卡,然后是命名文件中的关键字行,然后是文件1中的第9个字段
这可以写成(只有一种可能的解决方案):
gawk-vofs='\t''
argid
i、 e.在“file1”上调用awk一次,获取包含所需日期信息的文件列表,然后在“file1”之前再次将该文件列表传递给awk,以便最终处理file1时所需的所有信息都存储在数组中
上面使用GNU awk的“nextfile”来提高效率,但这不是必需的,为了清晰起见,使用GNU awk ARGID,但您可以用文件名替换ARGID有许多替代解决方案,这取决于您真正想做什么……感谢Ed和Zsolt的帮助。最后,我决定改用shell脚本,因为除了
grep
命令之外,我还需要一个sed
命令,该命令由于其所需的特殊特性而产生各种各样的问题。因此,我的最终解决方案如下:
fileList=`ls -1 *.xml`
for f in ${fileList} ; do
my_year=`grep -e "key_word" ${f} | sed -n '{s/^.*>\([0-9][0-9]*\)<.*$/\1/p}'`
line=`ls -ltr ${f}`
line="${line} ${my-year} sthElseHere"
echo ${line}
done | \
awk ' BEGIN {print "File Name \tcol02 \tcol03 "
print "=================== \t====== \t============"}
{printf "%s\t%s\t%s\n", $8, $4, $9 }'
fileList=`ls-1*.xml`
对于${fileList}中的f;做
my_year=`grep-e“关键字”${f}sed-n'{s/^.*>\([0-9][0-9]*\)您的建议对我部分有效。它确实执行grep,但变量my_year(或系统命令的执行)除外包括我不想要的进位返回,因为它向文件中添加了一个额外的CR。我添加了$9,以便您可以看到$8之后,返回被添加到两行输出记录中。它还添加了一个在第一行输出中找不到的sh:0:命令。实际上,执行的是系统命令在“getline”获取任何内容。“my_year”变量没有获取任何值。换句话说,我看到的输出是系统命令的输出,而不是函数返回的内容。我正在尝试添加“|tr-d”\n"
但我不知道参数应该在什么地方。这绝对是错误的做法。你试图将awk用作外壳-不要这样做,即使你可以强制它执行并生成你想要的输出,awk也不擅长。惊喜,惊喜,外壳非常擅长。如果你告诉我们你真正想要做的是什么,我们会告诉你可能会有帮助。但是如果您的脚本位于文件中并且是源代码,您可以使用单引号,例如awk-f yourscript
。非常感谢。这帮助我理解了在单引号脚本中使用单引号的问题。注意:我知道我可以使用纯shell脚本获得类似的输出,但我需要编写更多的脚本用if
或为
语句编码行。在这种情况下,我所需要的只是更改输入列的顺序,并在它们之间添加一个额外的列。我绝对不是建议在shell中编写整个脚本,我只是建议可能有更好的方法来执行您尝试执行的任何操作,因为有shell调用awk调用shell几乎总是错误的方法,在awk中使用getline充满了危险。我敢打赌,只要采用正确的方法,您在awk中所做的任何事情都是微不足道的。如果您发布另一个带有一些示例输入和预期输出的问题,我相信我们可以帮助您。
fileList=`ls -1 *.xml`
for f in ${fileList} ; do
my_year=`grep -e "key_word" ${f} | sed -n '{s/^.*>\([0-9][0-9]*\)<.*$/\1/p}'`
line=`ls -ltr ${f}`
line="${line} ${my-year} sthElseHere"
echo ${line}
done | \
awk ' BEGIN {print "File Name \tcol02 \tcol03 "
print "=================== \t====== \t============"}
{printf "%s\t%s\t%s\n", $8, $4, $9 }'