从字符串中获取令牌,直到它们在 shell 脚本中耗尽



我有一个 shell 脚本,它从 stdin 读取输入字符串,只从输入中获取部分值。 输入字符串可以具有任意数量的键/值对,格式如下:

{"input0":"name:/data/name0.csv",
 "input1":"name:/data/name1.csv",
 ....}

所以在上面的例子中,我想将这些作为我的脚本的输出:

/data/name0.csv
/data/name1.csv
.....

我想我需要两个 while 循环,一个需要继续从 stdin 读取,另一个需要从输入中提取值,直到没有更多。 有人可以让我知道如何做第二个循环块吗?

如果你有

{"input0":"name:/data/name0.csv",
    "input1":"name:/data/name1.csv",
    ....}

在文件abc.in 中,您可以使用名为 sed 的命令执行以下操作来解析输入:

cat abc.in | sed 's/.*"input[0-9]+":"name:(/data/name[0-9]+.csv)".*$/1/g'

基本上使用正则表达式查找当前行,并查看它是否匹配以下形式之一 行首 然后是任何东西"输入和一个数字":"名称:/数据/名称和一个数字.csv"任何东西,然后是行尾。结果是:

/data/name1.csv
/data/name2.csv
/data/name3.csv
/data/name4.csv
...

一个简单的 BashFAQ #1 循环在这里工作,jq将字符串预处理为面向行的内容:

while read -r value; do
  echo "${value#name:}"
done < <(jq -r '.[]')

也就是说,您实际上可以在jq中完成整个操作,而完全没有bash;以下内容将给定的输入直接转换为所需的输出(给定jq 1.5或更高版本):

jq -r '.[] | sub("name:"; "")'

如果你真的想以脆弱的方式做事,而不是利用JSON解析器,你也可以这样做:

# This is evil: Will fail very badly if input formatting changes
content_re='"name:(.*)"'
while read -r line; do
  [[ $line =~ $content_re ]] && printf '%sn' "${BASH_REMATCH[1]}"
done

仍然不需要内部循环 - 只需要一个循环遍历输入行,由主体确定如何处理每一行。

相关内容

  • 没有找到相关文章

最新更新