【问题标题】:Regex operation over each line of text-file, write to new file对文本文件的每一行进行正则表达式操作,写入新文件
【发布时间】:2014-05-08 09:52:45
【问题描述】:

我正在寻找一种在 bash 中执行以下操作的方法:

  1. 指定输入文件 (JSON)

  2. 将每一行写入一个新文件(行可能受正则表达式模式的限制,但不是必需的)

  3. 以文件中的特定 JSON 值命名每个文件

在之前的尝试中,我尝试对任务使用简单的split(没有命名部分),但在执行一定数量的行后它就退出了。我最大的文件大约有 1000 行。

示例输入:

{
        "stuff":
        [
            { "data": "123", "filename": "abc.xml" },
            { "data": "456", "filename": "def.xml" },
            { "data": "789", "filename": "ghi.xml" }
       ]
}

示例输出:

abc.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<data>123</data>

def.xml的内容:

<?xml version="1.0" encoding="UTF-8"?>
<data>456</data>

PS:选择这个例子只是为了让你有个想法,尽管输入文件类似于我的真实场景。

【问题讨论】:

  • 发布一些示例输入和预期输出。
  • 两个 Q: 1) 为什么这必须通过 awk/bash 来完成?编程/脚本语言中有许多 json 解析器/转换器。 2) 如果您确实有合理的理由使用 bash/awk,那么您为实现目标做了什么?哪一部分有问题?
  • @Kent 主要问题显然是根据 JSON 文件中的值创建文件。我之前使用split 按行拆分文件,然后在 Subliem Text 中执行 Regex 搜索和替换来编辑单个文件。这并没有解决我的主要问题:文件的命名。此外,split被证明是不可靠的。我的 JSON 文件中的总行数大约为 9,000 行,以供您参考。
  • @idleberg 这个要求对我来说不够清楚。例如。 1)你说的json,结构可能与你的例子完全不同。 2) 如果您只想处理匹配data:xxx,filename:xxx 的那些行?格式是固定的吗?这是文本处理工具的重要信息。 3)可以有嵌套对象吗?比如data: foo[...data: bar [...]] filename 4) 我能理解你的问题是将文本"data": "123", "filename": "abc.xml" 转换为abc.xml 中的文本吗?
  • @Kent 1.) JSON 的结构与我的场景相匹配。目标格式并不重要,它可以是 JSON,只要名称是从源 JSON 中提取的。 2. 除开/关括号外,不会有其他行。 3.) 没有嵌套对象。 4.) 完全正确

标签: regex bash awk terminal gawk


【解决方案1】:

既然你说格式是固定的,这对你有用:

kent$  ls 
f


kent$  awk -F'"' '/data/{printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%s>%s</%s>\n", $2,$4,$2>$8; close($8) }' f

kent$  ls                                                                                                               
abc.xml  def.xml  f  ghi.xml

kent$  head *.xml
==> abc.xml <==
<?xml version="1.0" encoding="UTF-8"?>
<data>123</data>

==> def.xml <==
<?xml version="1.0" encoding="UTF-8"?>
<data>456</data>

==> ghi.xml <==
<?xml version="1.0" encoding="UTF-8"?>
<data>789</data>

【讨论】:

  • @MikeH-R 不解析 json/xml/html/... 不是 awk 的好用例。
  • 哈哈哈,不,当然不是,我只是说本质上是 csv 数据,因为 OP 说数据是这样的常规数据。
【解决方案2】:

我认为 awk 是一种更好的方法,如果你想要的是纯 bash,那么你可以试试这个:

➜  scripts  cat my_bash_example.sh
#!/bin/bash

while read -r variable; do
    if [[ "$variable" =~ .*\.xml ]]; then
        echo "making xmlfile"
        echo $variable;
        cat temp.tmp > $variable
    else
        echo "making tempfile"
        echo $variable
        echo $variable > temp.tmp
    fi
    done
➜  scripts  cat input.json | grep data | grep -oP '(?<=data": "|filename": ").*?(?=")' | my_bash_example.sh

我决定用它来练习我的管道、grep 和 bash_scripts。虽然它有点难看,(并且在很多情况下都会中断)。我更喜欢 awk。

哦,顺便说一句,我使用了 bash,因为那是问题中所说的,如果我自己这样做,我会使用脚本语言。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-29
    • 2022-08-17
    • 1970-01-01
    • 2016-12-25
    相关资源
    最近更新 更多