Awk反转行和单词

7

我对编程语言和相关知识很陌生,所以我需要使用awk反转文件中的所有行和单词,并将它们打印出来。

需要反转的文件名为"File1":

aa bb cc

foo do as

"File1"的输出结果应该是这样的:

as do 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

问题是我在这方面是初学者,不知道如何将这两个东西结合起来。 谢谢!


+1 非常好的问题(第一次提问还这么好)。良好的格式,样例输入,样例输出和不工作的代码!干得好,继续发布! - shellter
3个回答

3
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

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"

一些系统在访问标准错误输出时采用了不同的符号表示方法,如果你需要经常这样做,那么了解其它可用方式是值得的。

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]) ) }

我希望这有所帮助。

3
使用 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))'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接