在 Unix 系统上查找数据的最佳工具和技巧

有时候在 Unix 系统上查找信息就如同大海捞针。如果重要的信息被淹没在大量文本中,它们也很难被注意到。目前我们中的很多人都在处理“大数据” —— 从数十亿字节大小的日志文件和巨大的各种格式记录集合中挖掘商业情报。

幸运的是,只有在两种情况下,你才需要在成堆的数据中挖掘,继而完成你的工作 —— 当你知道你要找什么和当你不知道的时候。:) 最佳工具和技巧取决于你面临两种情况中的哪一种。

当你知道的时候

当你知道你要找什么,grep 就是你的朋友,这不只是在你查找特定文本的时候。grep 命令可以帮助你找到任意文本,特定单词,文本模式和有上下文的文本。当你知道文本长什么样时,查找它通常很简单。grep this that 命令会显示“that”文件中包含“this”字符串的每一行。增加 -w 选项就只会显示那些单独包含“this”这个单词的行。换句话说,如果行中包含“thistle” 或 “erethism” 就不会显出来,除非这些行也有 “this” 这个单词。

最简单的 grep 命令不费什么力气就能理解:

    $ grepfind poemfinding meaning, finding comfort,finding someone to adoreCan we find a way to be

查找整个单词可以通过增加 -w 选项完成:

    $ grep-wfind poemCan we find a way to be

查找模式需要一点技巧。我们的第一个例子中显示了包含“find”单词的行,无论“find”中的“f”是大写还是小写:

    $ grep[Ff]ind poemFinding answersfinding meaning, finding comfort,finding someone to adoreCan we find a way to be

如果你想匹配以文本起始或结束的行,你可以使用 ^(起始)或 $(结尾)。

    $ grep^find poemfinding meaning, finding comfort,finding someone to adore

如果你想找到包含两个连续元音音节的单词的行,你可以使用如下所示的“AEIOUaeiou”字符。

    $ grep-E "[AEIOUaeiou]{2}" poem |head-3Allour days are filled with searchingwondering what we're looking forfinding meaning, finding comfort,

查找包含 9 个或者 10 个字母的字符串:

    $ grep-E "[[:alpha:]]{9,10}" poemAllour days are filled with searchingwondering what we're looking forAll our days are filled with searchingthat makes the searching more productive

查找一个包含 “find” 的长单词:

    $ grep-E "find[^[:space:]]+" poemfinding meaning, finding comfort,finding someone to adore

我们中的大多数人不会去查找诗歌,这是显而易见的,但我们可以使用同样的技巧来从我们的系统文件中获取相关的信息。在下面的例子里,我们查找”processor”这个术语,并且按照五行一组(前置两行后置两行)显示出来以便提供一些上下文。如果你希望得到 9 行一组,将 -C 2 变成 -C 4 就可以了。

    $ grep-C 2 processor /var/log/dmesgUsing ACPI (MADT)for SMP configuration informationAllocating PCI resources starting at 88000000(gap:80000000:7ec00000)Detected3400.426MHz processor.Built1 zonelists.Total pages:524275Kernel command line: ro root=LABEL=/1--Inode-cache hash table entries:65536(order:6,262144 bytes)Memory:2071140k/2097100k available (2223k kernel code,24616k reserved,922k data,232kinit,1179596k highmem)Checkingifthis processor honours the WP bit even in supervisor mode...Ok.Calibrating delay loop (skipped), value calculated using timer frequency..6800.85BogoMIPS(lpj=3400426)SecurityFramework v1.0.0 initialized--CPU0:Intel(R)Xeon(TM) CPU 3.40GHz stepping 04SMP alternatives: switching to SMP codeBooting processor 1/1 eip 11000CPU 1 irqstacks, hard=c0779000 soft=c0759000Initializing CPU#1--CPU1:Intel(R)Xeon(TM) CPU 3.40GHz stepping 04SMP alternatives: switching to SMP codeBooting processor 2/6 eip 11000CPU 2 irqstacks, hard=c077a000 soft=c075a000Initializing CPU#2--CPU2:Intel(R)Xeon(TM) CPU 3.40GHz stepping 04SMP alternatives: switching to SMP codeBooting processor 3/7 eip 11000CPU 3 irqstacks, hard=c077b000 soft=c075b000Initializing CPU#3

当你不知道的时候

如果你要查找一个已知位置的文本,例如当 Perl 告诉你脚本执行到第 73 行出现了问题,或者你正在处理文件的第 1892 行,你可以使用sed 来显示特定的行(我只是不喜欢数到 1892 行)。而且额外花一点点力气,你就可以只显示这一行。

错误信息可能像这个样子:

    “syntax error line 73 near ”}else“”

你可以使用一个sed命令来显示出问题的这行:

    $ sed-n 73p showvarselse

好了,就是这行,但是我们也没有比之前多知道些什么。通过显示前面几行可以增加一点上下文信息,我们就可以定位错误。这里有一个类似的命令可以显示这行和之前的十行:

    $ sed-n 63,73p showvarsif $password eq "a_secret";{foreach $var (sort(keys(%ENV))){$val = $ENV{$var};$val =~ s|n|n|g;$val =~ s|"|"|g;print'${var}="${val}"n'};}else

哎呦!这看上去是某些人在写 if 语句时出了问题!我们可以很容易地修复它。

你还可以使用 sed 命令来强调包含特定内容的行。在下面的命令里,我们增加了一个 “箭头标记” 来强调每一个包含 foreach 命令的行:

    $ sed'/print/{b label1; {:label1 ; s/^/# / ; s/$/ <===/ ;} }' showvars#!/bin/bashif $password eq "a_secret";{foreach $var (sort(keys(%ENV))){$val = $ENV{$var};$val =~ s|n|n|g;$val =~ s|"|"|g;#print'${var}="${val}"n'<===};}else

你可以使用类似的命令注释掉你的 print 命令:

    $ sed'/print/{b label1; {:label1 ; s/^/# / ; s/$/ <===/ ;} }' showvars#!/bin/bashif $password eq "a_secret";{foreach $var (sort(keys(%ENV))){$val = $ENV{$var};$val =~ s|n|n|g;$val =~ s|"|"|g;#print'${var}="${val}"n'<===};}else

大海捞针很难,其实地毯上找针也都不容易。但是通过使用一些最常见 Unix 命令的变形,就可以很容易找到你要找的东西,甚至当你并不知道要找什么的时候。

莫找借口失败,只找理由成功。

在 Unix 系统上查找数据的最佳工具和技巧

相关文章:

你感兴趣的文章:

标签云: