博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在 Unix 系统上查找数据的最佳工具和技巧
阅读量:5816 次
发布时间:2019-06-18

本文共 4047 字,大约阅读时间需要 13 分钟。

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

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

当你知道的时候

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

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

 
  1. $ grep find poem
  2. finding meaning, finding comfort,
  3. finding someone to adore
  4. Can we find a way to be

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

 
  1. $ grep -w find poem
  2. Can we find a way to be

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

 
  1. $ grep [Ff]ind poem
  2. Finding answers
  3. finding meaning, finding comfort,
  4. finding someone to adore
  5. Can we find a way to be

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

 
  1. $ grep ^find poem
  2. finding meaning, finding comfort,
  3. finding someone to adore

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

 
  1. $ grep -E "[AEIOUaeiou]{2}" poem | head -3
  2. All our days are filled with searching
  3. wondering what we're looking for
  4. finding meaning, finding comfort,

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

 
  1. $ grep -E "[[:alpha:]]{9,10}" poem
  2. All our days are filled with searching
  3. wondering what we're looking for
  4. All our days are filled with searching
  5. that makes the searching more productive

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

 
  1. $ grep -E "find[^[:space:]]+" poem
  2. finding meaning, finding comfort,
  3. finding someone to adore

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

 
  1. $ grep -C 2 processor /var/log/dmesg
  2. Using ACPI (MADT) for SMP configuration information
  3. Allocating PCI resources starting at 88000000 (gap: 80000000:7ec00000)
  4. Detected 3400.426 MHz processor.
  5. Built 1 zonelists. Total pages: 524275
  6. Kernel command line: ro root=LABEL=/1
  7. --
  8. Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
  9. Memory: 2071140k/2097100k available (2223k kernel code, 24616k reserved, 922k data, 232k init, 1179596k highmem)
  10. Checking if this processor honours the WP bit even in supervisor mode... Ok.
  11. Calibrating delay loop (skipped), value calculated using timer frequency.. 6800.85 BogoMIPS (lpj=3400426)
  12. Security Framework v1.0.0 initialized
  13. --
  14. CPU0: Intel(R) Xeon(TM) CPU 3.40GHz stepping 04
  15. SMP alternatives: switching to SMP code
  16. Booting processor 1/1 eip 11000
  17. CPU 1 irqstacks, hard=c0779000 soft=c0759000
  18. Initializing CPU
  19. #1
  20. --
  21. CPU1: Intel(R) Xeon(TM) CPU 3.40GHz stepping 04
  22. SMP alternatives: switching to SMP code
  23. Booting processor 2/6 eip 11000
  24. CPU 2 irqstacks, hard=c077a000 soft=c075a000
  25. Initializing CPU
  26. #2
  27. --
  28. CPU2: Intel(R) Xeon(TM) CPU 3.40GHz stepping 04
  29. SMP alternatives: switching to SMP code
  30. Booting processor 3/7 eip 11000
  31. CPU 3 irqstacks, hard=c077b000 soft=c075b000
  32. Initializing CPU
  33. #3

当你不知道的时候

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

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

 
  1. syntax error line 73 near ”} else

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

 
  1. $ sed -n 73p showvars
  2. else

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

 
  1. $ sed -n 63,73p showvars
  2. if $password eq "a_secret";
  3. {
  4. foreach $var (sort(keys(%ENV))) {
  5. $val = $ENV{
    $var};
  6. $val =~ s|n|n|g;
  7. $val =~ s|"|"|g;
  8. print '${var}="${val}"n'
  9. };
  10. }
  11. else

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

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

 
  1. $ sed '/print/{b label1; {:label1 ; s/^/# / ; s/$/ <===/ ;} }' showvars
  2. #!/bin/bash
  3. if $password eq "a_secret";
  4. {
  5. foreach $var (sort(keys(%ENV))) {
  6. $val = $ENV{
    $var};
  7. $val =~ s|n|n|g;
  8. $val =~ s|"|"|g;
  9. # print '${var}="${val}"n' <===
  10. };
  11. }
  12. else

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

 
  1. $ sed '/print/{b label1; {:label1 ; s/^/# / ; s/$/ <===/ ;} }' showvars
  2. #!/bin/bash
  3. if $password eq "a_secret";
  4. {
  5. foreach $var (sort(keys(%ENV))) {
  6. $val = $ENV{
    $var};
  7. $val =~ s|n|n|g;
  8. $val =~ s|"|"|g;
  9. # print '${var}="${val}"n' <===
  10. };
  11. }
  12. else

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

本文来自云栖社区合作伙伴“Linux中国”,原文发布日期:2015-10-19   

转载地址:http://duhbx.baihongyu.com/

你可能感兴趣的文章
利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用
查看>>
重构——61字段下移(Push Down Field)
查看>>
[20170619]11G expand sql text.txt
查看>>
Yarn源码分析之如何确定作业运行方式Uber or Non-Uber?
查看>>
信号槽库:sigslot.h和sigc++使用
查看>>
微信公众号运营架构图
查看>>
map的erase()释放内存
查看>>
spring-boot | 整合Redis缓存数据
查看>>
国外研究员研发薄而柔韧的新柔性材料 拉伸和压缩可产生电流
查看>>
多进程问题
查看>>
【编程练习】复习一下树的遍历
查看>>
电视台成阿里云下一个大数据重塑目标
查看>>
5G:在期待中缓行
查看>>
RabbitMQ管理(1)——多租户与权限
查看>>
Android Studio2.2 使用CMake编译 C/C++
查看>>
vivo独家冠名天猫双十一狂欢夜,一个新的经典即将到来
查看>>
微软为啥让免费升Win10?
查看>>
SaaS与云计算的区别
查看>>
关于SQLServer的游标类型、锁定类型
查看>>
JAVA通信编程(三)——TCP通讯
查看>>