Awk的FNR == NR与Ruby等效吗? [英] What is the Ruby equivalent of Awk's FNR==NR?
问题描述
Awk具有内置变量FNR
和NR
,用于存储从当前文件读取的记录数(通常为行)以及总数.
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 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
中有一个行号列表,并且想要使用这些行号建立索引的文本文件(可以使用awk
或sed
进行操作),则可以使用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屋!