在输出中打印特定部分


11

让我们假设有一个命令,例如:

cat /boot/config-3.19.0-32-generic | grep CONFIG_ARCH_DEFCONFIG

输出是这样的:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"

现在,我的问题是:是否有任何命令只能打印反逗号内的内容,即" "

您能解释一下该命令吗?谢谢!提前。


5
注意,cat在管道中使用几乎总是浪费资源(AKA UUOC)。grep可以从文件中读取其输入(即grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-generic,完全相同,但是1.较短。2.易于理解。3.不需要派生额外的shell和额外的过程)。在99%的情况下,在管道的开头使用cat而不串联多个文件只是有害的。:)
kos 2015年

@kos-谢谢!不知道,因为我刚开始使用linux。将牢记在心。
拉斐尔2015年

Np!我在上面留下我的评论,以供其他人绊倒这个问题。
kos 2015年

最初cat的命令虽然在这种情况下没有用,但将来使您更容易编辑整行命令,以防您以后要更改/添加/删除某些内容,例如a trcut等,而不必查找和移动文件名,确保其他命令支持它,找到放置它的位置,等等。对于一个小的测试文件,它仅增加0.002s。(我花了很多时间来键入此内容,这比我避免一辈子避免使用cat
它所

1
@ Xen2050为什么在cat这里提供帮助?您可以做到grep foo file | tr... | cut与之一样轻松cat file | tr | grep ...。该cat只是增加了一个额外的5个字符,一个额外的管道和一个额外的程序调用无法简化事情。
terdon 2015年

Answers:


15

是的,你可以这样做。您的命令将是:

cat /boot/config-3.19.0-32-generic | grep CONFIG_ARCH_DEFCONFIG | awk -F'"' '{print $2}'

只会返回:

arch/x86/configs/x86_64_defconfig

awk命令与该命令一起使用字段分隔符-F,并将其设置为使用双引号,您可以在它周围加上单引号将其键入-F'"'。然后,'{print $2}'告诉awk打印字段分隔符之后的第二组。

希望这可以帮助!


14
@Terrance,在这种情况下,这是对cat和的无用用法grep。您可以用替换catgrep分开awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic 。减少管道工作量,让AWK可以完成所有工作,这超出了他们的能力
Sergiy Kolodyazhnyy 2015年

同意@Serg
Tung Tran

@Serg没问题。我明白你在说什么。我只是通过添加命令来添加到他的原始awk命令。=)
Terrance

11

您可以使用一个grep命令来做到这一点:

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K[^"]*' /boot/config-3.19.0-32-generic

或(时间更长,更易被困扰):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
  • -P:告诉grep将模式解释为PCRE(Perl兼容正则表达式);
  • -ogrep仅显示匹配项;
  • ^CONFIG_ARCH_DEFCONFIG=":匹配行首的CONFIG_ARCH_DEFCONFIG="字符串;
  • \K:丢弃先前匹配的子字符串;

#1:

  • [^"]*:不匹配"(贪婪地)匹配任意数量的任意字符。

#2:

  • .*?:(任意)匹配任意数量的任何字符;
  • (?="):先行(零长度断言,不匹配任何字符);如果以下字符是,则匹配"
% grep -Po '^CONFIG_ARCH_DEFCONFIG="\K[^"]*' /boot/config-4.2.0-16-generic
arch/x86/configs/x86_64_defconfig
% grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-4.2.0-16-generic
arch/x86/configs/x86_64_defconfig

我喜欢学习获得相同结果的多种方法。好答案!=)
Terrance

10

有很多方法可以给这只猫蒙皮,这是一种sed方法:

sed -nr 's/^CONFIG_ARCH_DEFCONFIG="([^"]+)"$/\1/p' /boot/config-3.19.0-32-generic

在这里,我们匹配该行并捕获所需的部分,即双引号(([^"]+))内的部分,然后仅将整个行替换为捕获的组(\1)。

例:

% sed -nr 's/^CONFIG_ARCH_DEFCONFIG="([^"]+)"$/\1/p' /boot/config-3.13.0-32-generic
arch/x86/configs/x86_64_defconfig

10

什么,没有perl

grep CONFIG_ARCH_DEFCONFIG /boot/config-3.19.0-32-generic | 
    perl -pe 's/.*?"([^"]*).*/$1/'

在应用给出的脚本后,它perl将使-p每行不整洁-e。在s/foo/bar/将取代foo使用bar。括号中的模式被“捕获”,可以称为$1$2... $N,其中$1捕获了第一个模式,$2第二个以此类推。正则表达式将查找所有内容,直到第一个引号(.*?"),然后捕获0个或多个非"字符([^"]*),然后再进行其他操作。整个内容将替换为捕获的模式。

您还可以将模式匹配保留为perl

perl -ne 's/.*CONFIG_ARCH_DEFCONFIG="([^"]*).*/$1/ && print' /boot/config-3.19.0-32-generic

2
我知道您会在某个时候加入:P +1
heemayl 2015年

然后,我会产生一个Python代码..
阿维纳什·拉吉

with open('/boot/config-3.19.0-32-generic') as f: for line in f: if line.startswith('CONFIG_ARCH_DEFCONFIG'): print line.split('"')[1]
Avinash Raj 2015年

@AvinashRaj好东西,请发贴吗?我也用正则表达式发布了一个。
Sergiy Kolodyazhnyy

8

下面是一个组合grepcut,做同样的工作。

$ grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-generic | cut -d"\"" -f2                                                
arch/x86/configs/x86_64_defconfig

说明:

  • grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-generic是标准grep语法:中找到行的部分grep [OPTIONS] PATTERN [FILE...]。输出通过管道到达下一个阶段
  • cut -d"\"" -f2。此部分使用剪切来剪切由特定定界符(由-dflag 指定)分隔的文本。我们必须用反斜杠转义双引号,以便shell允许将双引号作为cut命令的选项之一,而不是输入到shell本身。现在,cut将把从输出grep被作为分离"和分成三列,CONFIG_ARCH_DEFCONFIGarch/x86/configs/x86_64_defconfig,和空的空间。我们需要的行是第二列,这意味着我们需要使用-f2flag。

3

由于我目前正在学习的python是一个完全使用它的版本。

#!/usr/bin/env python
import re

reg = re.compile('CONFIG_ARCH_DEFCONFIG')

with open("/boot/config-3.19.0-32-generic") as file :
   for line in file:
       if reg.match(line):
           print line.split('"')[1]

样品运行:

DIR:/TECH-BOOKS
skolodya@ubuntu:$ ./extractString.py                                           
arch/x86/configs/x86_64_defconfig

DIR:/TECH-BOOKS
skolodya@ubuntu:$ cat ./extractString.py                                       
#!/usr/bin/env python
import re

reg = re.compile('CONFIG_ARCH_DEFCONFIG')

with open("/boot/config-3.19.0-32-generic") as file :
   for line in file:
       if reg.match(line):
           print line.split('"')[1]

压痕very7 Python中非常重要的..
阿维纳什·拉吉

1
您无需进行正则表达式,只需使用我的即是,line.startswith因为re.match它比startswith
Avinash Raj
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.