설명하다

설명하다

이런 파일이 있어요

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

첫 번째 발생: add {"id":{"s":, 두 번째 발생 add{"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(Internal Field Separator)라는 내장 변수가 있습니다. 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으로 모아서 ,"{"..."}"로 묶습니다. 이제 끝났습니다.

관련 정보