在输出中打印特定部分

Rap*_*ael 12 command-line text-processing

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

cat /boot/config-3.19.0-32-generic | grep CONFIG_ARCH_DEFCONFIG
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
Run Code Online (Sandbox Code Playgroud)

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

你能解释一下这个命令吗?谢谢!提前。

Ter*_*nce 16

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

cat /boot/config-3.19.0-32-generic | grep CONFIG_ARCH_DEFCONFIG | awk -F'"' '{print $2}'
Run Code Online (Sandbox Code Playgroud)

这只会返回:

arch/x86/configs/x86_64_defconfig
Run Code Online (Sandbox Code Playgroud)

awk命令在命令中使用字段分隔符-F,并将其设置为使用双引号,输入时用单引号括起来,如-F'"'. 然后'{print $2}'告诉 awk 在字段分隔符之后打印第二组。

希望这可以帮助!

  • @Terrance,在这种情况下,这是对 `cat` 和 `grep` 的无用使用。你可以用 `awk -F'"' '/CONFIG_ARCH_DEFCONFIG/{print $2}' /boot/config-3.19.0-32-generic` 替换 `cat` 和 `grep` 部分。减少管道,让 AWK 做所有的事情工作,它完全有能力做 (14认同)

kos*_*kos 11

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

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K[^"]*' /boot/config-3.19.0-32-generic
Run Code Online (Sandbox Code Playgroud)

或者(有点长,更紧张):

grep -Po '^CONFIG_ARCH_DEFCONFIG="\K.*?(?=")' /boot/config-3.19.0-32-generic
Run Code Online (Sandbox Code Playgroud)
  • -P:告诉grep将模式解释为 PCRE(Perl 兼容正则表达式);
  • -o: 告诉grep只打印匹配项;
  • ^CONFIG_ARCH_DEFCONFIG=": 匹配行首的CONFIG_ARCH_DEFCONFIG="字符串;
  • \K: 丢弃之前匹配的子串;

#1:

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

#2:

  • .*?: 匹配任意数量的任意字符(懒惰);
  • (?="): 前瞻(零长度断言,不匹配任何字符);如果以下字符是".
grep -Po '^CONFIG_ARCH_DEFCONFIG="\K[^"]*' /boot/config-3.19.0-32-generic
Run Code Online (Sandbox Code Playgroud)


hee*_*ayl 10

有很多方法可以给这只猫剥皮,这里有一个sed方法:

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

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

例子:

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


ter*_*don 10

什么,没有perl

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

perl-p应用由给定的剧本后RINT每一行-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
Run Code Online (Sandbox Code Playgroud)

  • 我知道你会在某个时候加入 :P +1 (2认同)

Ser*_*nyy 9

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

$ grep "CONFIG_ARCH_DEFCONFIG" /boot/config-3.19.0-32-generic | cut -d"\"" -f2                                                
arch/x86/configs/x86_64_defconfig
Run Code Online (Sandbox Code Playgroud)

解释:

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