Given:
$ head f?.txt
==> f1.txt <==
line 1
line 2
==> f2.txt <==
line 3
line 4
红宝石有ARGF流(别名为$<
如果你想感受 Perly),它要么读取 STDIN,要么从命令行打开文件。与以下行为相同awk
:
$ awk '{
printf("FILENAME: %s, FNR: %s, NR: %s, %s\n", FILENAME, FNR,NR,$0)}
' f?.txt
FILENAME: f1.txt, FNR: 1, NR: 1, line 1
FILENAME: f1.txt, FNR: 2, NR: 2, line 2
FILENAME: f2.txt, FNR: 1, NR: 3, line 3
FILENAME: f2.txt, FNR: 2, NR: 4, line 4
$ ruby -lne '
printf("FILENAME: %s, FNR: %s, NR: %s, %s\n", $<.file.path, $<.file.lineno, $., $_)
' f?.txt
FILENAME: f1.txt, FNR: 1, NR: 1, line 1
FILENAME: f1.txt, FNR: 2, NR: 2, line 2
FILENAME: f2.txt, FNR: 1, NR: 3, line 3
FILENAME: f2.txt, FNR: 2, NR: 4, line 4
如果你想同时阅读STDIN
和一个文件,你会使用-
对于文件占位符:
$ echo '123' | awk '1' - <(echo 456)
123
456
$ echo '123' | awk '1' <(echo 456) -
456
123
$ echo '123' | ruby -lne 'puts $_' - <(echo 456)
123
456
$ echo '123' | ruby -lne '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 ║
║ FILENAME ║ $<.file.path ║ Filename of file being processed ║
╚══════════╩═══════════════════╩═════════════════════════════════════════╝
所以如果你有一个行号列表f1
和一个您想要用这些行号索引的文本文件(您可以使用awk
or sed
做)可以使用 Ruby。
Given:
$ echo "1
2
44
2017" >f1
$ seq 10000 | awk '{print "Line", $1}' >f2
In 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 倍(使用 awk),但 Ruby 版本可以轻松支持 awk 无法支持的输入,例如 JSON、XML、复杂的 csv 等。
如果你想要相当于awk -v [same variable]
在 Ruby 中,使用多个-e
Ruby 中的命令执行行。
要打印n
awk 中文件的行n
作为 shell 变量:
awk -v n="${sh_n}" 'FNR==n{print; exit}' big_file.txt
or:
awk 'FNR==n{print; exit}' n="${sh_n}" big_file.txt
在 Ruby 中执行相同的操作,即传递值${sh_n}
对于 Ruby 程序,您可以执行以下操作:
ruby -e "n=${sh_n}.to_i" -e '$<.each_line{|line| if $.==n then puts line; exit(0) end}' big_file.txt
HERE是预定义的 Ruby 变量的列表。
HERE是全局变量的列表