解释

解释

我有一个这样的文件

103710:v2HAbAFH029324:[email protected]:localhost:Sent
103821:CCFE5609E3:[email protected]:localhost:bounced
103922:DFF19609E2:[email protected]:localhost:Deferred

我需要将其更改为

{"randomId":{"s":"103710"},"id":{"s":"v2HAbAFH029324"},"userId":{"s":"[email protected]"},"dns":{"s":"localhost"},"status":{"s":"Sent"}}
{"randomId":{"s":"103821"},"id":{"s":"CCFE5609E3"},"userId":{"s":"[email protected]"},"dns":{"s":"localhost"},"status":{"s":"bounced"}}
{"randomId":{"s":"103922"},"id":{"s":"DFF19609E2"},"userId":{"s":"[email protected]"},"dns":{"s":"localhost"},"status":{"s":"Deferred"}}

我想这样的代码

while read line
do     
        sed -i 's/^/{"randomId":{"s":"/' test
        echo $line

        echo $line | grep -q ":"
        [ $? -eq 0 ] && echo "/"{"id":{"s":/"
        [ $? -eq 1 ] && echo "/",{"userId":{"s":/"
        [ $? -eq 2 ] && echo "/",{"host":{"s":/"
        [ $? -eq 3 ] && echo "/",{"status":{"s":/"
        echo "$line | " ";
done < test

第一次出现 : 添加 {"id":{"s":,然后第二次出现添加{"userId":{"s":

答案1

grep/echo 块不会做任何有用的事情; $?将被设置一次——它不会迭代这些字段。

值得庆幸的是,似乎有一种更简单的方法可以做到这一点:只需将字段拆分为变量即可。值得庆幸的是,read可以为您做到这一点:

while IFS=':' read -r randomid id userid dns status; do
    printf '{"randomId":{"s":"%s"},"id":{"s":"%s"},"userId":{"s":"%s"},"dns":{"s":"%s"},"status":{"s":"%s"}}\n' \
           "$randomid" "$id" "$userid" "$dns" "$status"
done

使用printf而不是更熟悉的echo可以避免所有需要的\"序列。echo请注意行末尾的反斜杠以将其分开。

顺便说一句:您生成的格式称为 JSON,可能有工具可以帮助生成它(例如,杰克)。此外,如果您的字段可以包含双引号,则它可能需要自己的转义。

答案2

perl

perl -MJSON -F: -ple '@A = qw/randomId id userId dns status/; $_ = encode_json({map { shift @A => { "s" => $_ } } @F } )' input.csv

答案3

由于您的数据是分隔的并且易于阅读,因此有几种方法可以做到这一点。 Sed 可以在一行中解析您的数据并输出更改:

sed -r -i 's/^(.*):(.*):(.*):(.*):(.*)$/{"randomId":{"s":"\1"},"id":{"s":"\2"},"userId":{"s":"\3"},"dns":{"s":"\4"},"status":{"s":"\5"}}/' input.txt

您可以使用捕获组来捕获文件开头、分隔符和文件结尾之间的所有内容,然后仅操作这些组周围的文本。每个捕获组均由“\#”引用,其中 # 是捕获组的编号,从 1 开始,每组递增 1。

正如已经提到的,您还可以设置自己的分隔符。 Bash 有一个称为 IFS(内部字段分隔符)的内置变量。 IFS 默认为空格,但您可以更改它。我不会展示 bash 示例,因为它已经给出,并且只是它的副本。

答案4

perl -F: -pale '
   @A = qw/randomId id userId dns status/;
   ($k, $_) = (0, "{" . join(",", map qq/"$A[$k++]":{"s":"$_"}/, @F) . "}");
' yourfile

解释

保留@F分割的字段:,然后通过适当的按摩将其缝合在一起{"s":"fieldI"},并以数组中的相应元素为前缀@A。所有这些元素都通过joinon聚集在一起,并括在“{”...“}”中。你就完成了。

相关内容