이런 파일이 있어요
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
. 이러한 모든 요소는 join
on으로 모아서 ,
"{"..."}"로 묶습니다. 이제 끝났습니다.