Awk具有内置变量FNR
和NR
,用于从当前文件中读取的记录数(通常为行)。
在awk中,通常有:
$ awk 'FNR==NR {first file lines; next } {process remaining lines } f1 f2
通常,f1
包含确定如何处理剩余文件的值。 (关键词,行号等)
Ruby拥有令人难以置信的文本处理语言。 Ruby有$.
等同于awk的NR
什么相当于FNR
?
答案 0 :(得分:2)
Ruby有ARGF stream(别名为$<
,如果你想感受Perly),它可以读取STDIN或从命令行打开文件。与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
和文件,可以使用-
作为文件占位符:
$ 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。
假设:
$ echo "1
2
44
2017" >f1
$ seq 10000 | awk '{print "Line", $1}' >f2
在awk
你会做:
$ awk 'FNR==NR{ln[$1]; next}
FNR in ln' f1 f2
在Ruby中你可以做到:
$ 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倍(go awk),但Ruby版本可以轻松支持awk无法输入的输入,例如JSON,XML,复杂csv等