【问题标题】:Awk reverse both lines and wordsawk 反转行和单词
【发布时间】:2012-04-11 02:06:06
【问题描述】:

我是编程语言和其他东西的新手 所以我必须用 awk 从文件中反转所有行以及这些行中的所有单词并将它们打印出来。

“文件1”要反转:

aa bb cc

做的事

“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

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

【问题讨论】:

  • +1 提出了很好的问题(也是第一次!)。良好的格式、示例输入、示例输出和不起作用的代码!好节目,继续发帖!

标签: awk reverse


【解决方案1】:

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

我希望这会有所帮助。

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案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))'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-04
        • 2018-05-19
        • 2021-04-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-13
        相关资源
        最近更新 更多