Awk反转两行和单词

时间:2012-03-27 14:13:09

标签: awk reverse

我是编程语言和新手的新手 所以我必须用awk反转所有的行以及那些行中的所有单词,从文件中打印出来。

“File1”反转:

  

aa bb cc

     

foo做

“File1”的输出打印应为:

  

和foo一样

     

cc bb aa

我在每一行尝试了反向词:

for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)

但如果我想要打印反转的线条,我必须这样做

{a[NR]=$0
}END{for(i=NR; i; i--) print a[i]}

我需要在终端中使用此命令处理两个文件:

awk -f commandFile FileToBePrinted

问题是我在这一切都是开始的,我不知道如何将这两者结合起来。 谢谢!

3 个答案:

答案 0 :(得分:3)

Kev的解决方案试图扭转每个单词中的文本。你的示例输出没有显示,但他的关键点是使用函数。

您拥有所需的代码,只需稍微重新排列即可。

cat file1
aa bb cc
foo do as

cat commandFile

function reverse( line ) {
  n=split(line, tmpLine)
  for (j=n; j>0; j--) {
    printf("%s ",tmpLine[j] )
  }

}
# main loop
{ a[NR]=$0 }

# print reversed array
END{ for(i=NR; i>0; i--) printf( "%s\n",  reverse(a[i]) ) }

运行

 awk -f commandFile file1

<强>输出

as do foo
cc bb aa

我使用n=split(line, tmpLine) ... print tmpLine[j]进行了一些小的更改,这是在函数中解析输入行以将其打印出来的常用方法。我不认为1美元的变量具有来自数组传递的值的范围(你的a [i]值),因此我将其更改为split..tmpLine [j]。我还发现END部分的'i'变量保留在函数reverse的范围内,因此我将其更改为j以消除歧义。


我必须弄清楚一些事情,所以下面是我使用的调试版本。

如果您打算访问gawk,那么您将学习如何使用可用的调试器。如果您在没有调试器的系统上使用awk / gawk / nawk,那么这是一种了解代码中发生情况的方法。如果要将程序输出重定向到文件或管道,并且如果系统支持“/ dev / stderr”表示法,则可以在那里打印调试行,即

 #dbg print "#dbg0:line=" line > "/dev/stderr"

有些系统还有其他用于访问stderr的符号,所以如果你要这么做,那么找出可用的东西是值得的。

cat commandFile.debug
function reverse( line ) {
  n=split(line, tmpLine)
  #dbg print "#dbg0:line=" line
  #dbg print "#dbg1:n=" n "\tj=" j "\ttmpLine[j]=" tmpLine[j]
  for (j=n; j>0; j--) {
    #dbg print "#dbg2:n=" n "\tj=" j "\ttempLine[j]=" tmpLine[j]
    printf("%s ",tmpLine[j] )
  }

}
# main loop
{ a[NR]=$0 }

# print reversed array
#dbg END{ print "AT END";  for(i=NR; i>0; i--) printf( "#dbg4:i=%d\t%s\n%s\n", i, a[i] , reverse(a[i])
 ) }
END{ for(i=NR; i>0; i--) printf( "%s\n",  reverse(a[i]) ) }

我希望这会有所帮助。

答案 1 :(得分:2)

awk '
{
    x=reverse($0) (x?"\n":"") x
}

END{
    print x
}

function reverse(s,    p)
{
    for(i=length(s);i>0;i--)
        p=p substr(s,i,1)
    return p
}' File1

答案 2 :(得分:2)

使用tac来反转文件的行,然后awk反转单词。

tac filename | awk '{for (i=NF; i>1; i--) printf("%s ",$i); printf("%s\n",$1)}'

你也可以使用类似Perl的内置列表反转功能的东西:

tac filename | perl -lane 'print join(" ", reverse(@F))'