我如何获得第一个双引号中的值?

How do i get the value present in first double quotes?

我目前正在编写一个 bash 脚本来获取许多逗号分隔字符串中的第一个值。 我有一个看起来像这样的文件 -

name


things: "water bottle","40","new phone cover",10



place

我只需要 return 第一个双引号中的值。

water bottle

第一个双引号中的值可以是一个 word/two 个单词。也就是说,water bottle有时可以用pen代替。 我试过了 -

awk '/:/ {print }'

但这只是给

water

我想用逗号分隔,但是things后面有colon(:)。所以,我不确定如何将它分开。 我如何获得第一个双引号中的值?

编辑:

解决方案: 我使用了下面的代码,因为我特别想使用 awk -

awk '/:/' test.txt | cut -d\" -f2

方案一:awk

您可以使用单个 awk 命令:

awk -F\" 'index(, ":"){print }' test.txt > outfile

参见online demo

-F\" 将字段分隔符设置为 " 字符,index(, ":") 条件确保字段 1 包含 : 字符(不需要正则表达式)然后 {print } 打印第二个字段值。

方案二:awk + cut

您可以使用 awk + cut:

awk '/:/' test.txt | cut -d\" -f2 > outfile

使用 awk '/:/' test.txt,您将提取包含 : 字符的行,然后管道 cut -d\" -f2 命令将使用 " 作为分隔符拆分字符串return 第二项。见 online demo.

方案三:sed

或者,您可以使用 sed:

sed -n 's/^[^"]*"\([^"]*\)".*//p' file > outfile

参见 online demo:

#!/bin/bash
s='name
things: "water bottle","40","new phone cover",10
place'
 
sed -n 's/^[^"]*"\([^"]*\)".*//p' <<< "$s"
# => water bottle

命令表示

  • -n - 该选项抑制默认行输出
  • ^[^"]*"\([^"]*\)".* - 匹配的 POSIX BRE 正则表达式模式
    • ^ - 字符串开头
    • [^"]* - "
    • 以外的零个或多个字符
    • " - 一个 " 字符
    • \([^"]*\) - 第 1 组(</code> 指的是此值):除 <code>"
    • 之外的任何零个或多个字符
    • ".* - " 字符和字符串的其余部分。
  • </code> 用组 1 值替换匹配项</li> <li><code>p - 仅打印成功替换的结果。

使用 cut 实用程序的解决方案可能是

cut -d\" -f2 infile > outfile

使用 gnu awk 你可以使用捕获组,并使用 negated character class 来不跨越 , 因为那是字段分隔符。

awk 'match([=10=], /^[^",:]*:[^",]*"([^"]*)"/, a) {print a[1]}' file

输出

water bottle

模式匹配

  • ^ 字符串开头
  • [^",:]*:可选择匹配除",:以外的任何值,然后匹配:
  • [^",]* 可选择匹配除 ",
  • 之外的任何值
  • "([^"]*)" 在组 1 中捕获双引号之间的值

如果值始终在双引号之间,获得所需结果的一个简短选项可能是将字段分隔符设置为 " 并检查第 1 组是否包含冒号,尽管从技术上讲您也可以获得 water bottle 如果只有前导双引号而不是右引号。

awk -F'"' ' ~ /:/ {print }' file

使用您展示的示例,请尝试以下 awk 代码。

awk '/^things:/ && match([=10=],/"[^"]*/){print substr([=10=],RSTART+1,RLENGTH-1)}' Input_file

解释:awk 程序中检查行是否以 things 开头: AND using match function to匹配第一个和第二个 " 之间的所有内容并相应地打印它们。