Awk的FNR == NR与Ruby等效吗? [英] What is the Ruby equivalent of Awk's FNR==NR?

查看:61
本文介绍了Awk的FNR == NR与Ruby等效吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Awk具有内置变量FNRNR,用于存储从当前文件读取的记录数(通常为行)以及总数.

Awk has the built in variables FNR and NR for the number of records (lines usually) read from the current file and in total.

在awk中,通常有:

$ awk 'FNR==NR {first file lines; next } {process remaining lines } f1 f2

通用(Common),f1包含确定如何处理剩余文件的值. (关键字,行号等)

Commonly, f1 contains values that determine how to process the remaining files. (key words, line numbers, etc.)

Ruby具有出色的文本处理语言. Ruby将$.等同于awk的NR什么等同于FNR?

Ruby has the makings of a fabulous text processing language. Ruby has $. as the equivalent of awk's NR What is equivalent of FNR?

推荐答案

Ruby具有

Ruby has the ARGF stream (aliased as $< if you want to feel Perly) that either reads STDIN or opens a file from the command line. Same behavior as awk:

$ awk '{print FNR,NR,$0}' f1 f2
1 1 line 1
2 2 line 2
3 3 line 3
1 4 LINE 1
2 5 LINE 2

$ ruby -lane 'puts [ARGF.file.lineno, $., $_].join(" ")' f1 f2 
1 1 line 1
2 2 line 2
3 3 line 3
1 4 LINE 1
2 5 LINE 2

如果要同时读取STDIN和文件,则可以将-用作文件占位符:

If you want to read both STDIN and a file, you would use a - for a file placeholder:

$ echo '123' | awk '1' - <(echo 456)
123
456
$ echo '123' | awk '1' <(echo 456) -
456
123

$ echo '123' | ruby -lane 'puts $_' - <(echo 456)
123
456
$ echo '123' | ruby -lane 'puts $_' <(echo 456) -
456
123

更多相应的变量:

╔═════════╦═══════════════════╦═════════════════════════════════════════╗
║   awk   ║       ruby        ║                 comment                 ║
╠═════════╬═══════════════════╬═════════════════════════════════════════╣
║ $0      ║ $_                ║ unsplit record (line usually)           ║
║ NF      ║ $F.length         ║ Number of fields from autosplit         ║
║ FNR     ║ ARGF.file.lineno  ║ Number records read from current source ║
║ NR      ║ ARGF.lineno or $. ║ Total number of records so far          ║
║ (magic) ║ ARGF or $<        ║ stream from either STDIN or a file      ║
║ $1..$NF ║ $F[0]..$F[-1]     ║ First to last field from autosplit      ║
║ FS      ║ $;                ║ Input field separator                   ║
║ RS      ║ $/                ║ Input record separator                  ║
╚═════════╩═══════════════════╩═════════════════════════════════════════╝  

因此,如果您在f1中有一个行号列表,并且想要使用这些行号建立索引的文本文件(可以使用awksed进行操作),则可以使用Ruby

So if you has a list of line numbers in f1 and a text file that you wanted to index with those line numbers (something you would use awk or sed to do) it is possible to use Ruby.

给出:

$ echo "1
2
44
2017" >f1
$ seq 10000 | awk '{print "Line", $1}' >f2

awk中,您将执行以下操作:

In awk you would do:

$ awk 'FNR==NR{ln[$1]; next} 
       FNR in ln'    f1 f2

在Ruby中,您可以这样做:

In Ruby you could do:

$ ruby -lane 'BEGIN{h=Hash.new}
              if $<.file.lineno == $<.lineno
                 h[$F[0].to_i]=true
                 next
              end
              puts $_ if h[$<.file.lineno]' f1 f2

两个打印:

Line 1
Line 2
Line 44
Line 2017

此示例的awk版本大约快5倍(转到awk),但Ruby版本将轻松支持awk无法提供的输入,例如JSON,XML,复杂的csv等

The awk version of this example is roughly 5x faster (go awk) but the Ruby version would easily support inputs that awk couldn't, such as JSON, XML, complex csv, etc

这篇关于Awk的FNR == NR与Ruby等效吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆