탭으로 구분된 값을 YAML로 변환

탭으로 구분된 값을 YAML로 변환

다음 형식의 탭으로 구분된 값이 있는 파일이 있습니다.

your-email  your-order-id   PayPal-transaction-id   your-first-name your-second-name
[email protected]   12345   54321   sooky   spooky
[email protected]   23456   23456   kiki    dee
[email protected] 34567   76543   cheeky  chappy

awk이것을 사용하여 YAML로 변환 하고 싶습니다 .

---

your-email: [email protected]
your-order-id: 12345
PayPal-transaction-id: 54321
your-first-name: sooky
your-second-name: spooky

your-email: [email protected]
your-order-id: 23456
PayPal-transaction-id: 23456
your-first-name: kiki
your-second-name: dee

your-email: [email protected]
your-order-id: 34567
PayPal-transaction-id: 76543
your-first-name: cheeky
your-second-name: chappy

지금까지 내 awk 스크립트는 다음과 같습니다.

#!/usr/bin/awk
FS=="\t"
BEGIN {print "---"} 
NR==1 {for (i=1;i<=NF;i++) print $i ": "}

하지만 1행부터 각 필드를 제목 뒤에 인쇄하고 입력 파일의 첫 번째 행에서 YAML 키 값을 다시 생성하는 방법을 모르겠습니다. 실제 파일에는 38개의 필드와 34개의 레코드가 있습니다(그래서 크지는 않음).

답변1

한 가지 방법은 다음과 같습니다.

$ cat inf
your-email  your-order-id   PayPal-transaction-id   your-first-name your-second-name
[email protected]   12345   54321   sooky   spooky
[email protected]   23456   23456   kiki    dee
[email protected] 34567   76543   cheeky  chappy
$ cat mkf.sh
awk '
BEGIN {
  print "---\n"
}
NR == 1 {
  nc = NF
  for(c = 1; c <= NF; c++) {
    h[c] = $c
  }
}
NR > 1 {
  for(c = 1; c <= nc; c++) {
    printf h[c] ": " $c "\n"
  }
  print ""
}' inf
$ ./mkf.sh inf
---

your-email: [email protected]
your-order-id: 12345
PayPal-transaction-id: 54321
your-first-name: sooky
your-second-name: spooky

your-email: [email protected]
your-order-id: 23456
PayPal-transaction-id: 23456
your-first-name: kiki
your-second-name: dee

your-email: [email protected]
your-order-id: 34567
PayPal-transaction-id: 76543
your-first-name: cheeky
your-second-name: chappy

답변2

0으로 설정된 시작에서 반복 가능한 정수 변수를 정의하고 "iter==0"이 필드 이름을 배열의 요소에 저장하는 경우 자동으로 정수를 증가시키는 if/else 문을 실행해 보셨나요? 그렇지 않으면 레코드가 인쇄되었습니다. 작성됨( i반복 가능한 인쇄 필드 사용 제외 ?(awk 배열에 대한 추가 정보).

나는 이 코드를 전혀 테스트하지 않았지만( awk일반적으로 이 코드는 정말 형편없지만) 일반적인 프로그래밍/스크립팅 개념을 구체적으로 설명하는 데 도움이 될 것입니다.

#!/usr/bin/awk
FS=="\t"
BEGIN {
   print "---"
   iter=0
} 
NR==1 
{

   if (iter == 0)
      for (i=1;i<=NF;i++) 
         newArr[i]=$i
      iter++
   else
      for (i=1;i<=NF;i++) 
         print newArr[i] ": " $i

}

답변3

이것이 가능하다고 확신 awk하지만 Perl의 답변이 수용 가능하다면 다음과 같이 필요한 작업을 수행해야 합니다.

#!/usr/bin/env perl
print "---\n";
while (<>) {
    chomp;
    ## This splits the line at one or more whitespace characters
    ## into the array @fields.
    @fields=split(/\t+/);
    ## Get the column names if this is the 1st line
    if ($.==1){@cols=@fields}
    ## Print the data if it is not the first line
    else {
      print "\n";
      for ($i=0;$i<=$#fields;$i++){
        print "$cols[$i] : $fields[$i]\n";
      }
    }
} 

예를 들어:

$./foo.pl input_text.txt
---

your-email: [email protected]
your-order-id: 12345
PayPal-transaction-id: 54321
your-first-name: sooky
your-second-name: spooky

your-email: [email protected]
your-order-id: 23456
PayPal-transaction-id: 23456
your-first-name: kiki
your-second-name: dee

your-email: [email protected]
your-order-id: 34567
PayPal-transaction-id: 76543
your-first-name: cheeky
your-second-name: chappy

-a이는 Perl의 옵션을 사용하여 각 줄을 배열로 분할하는 단일 줄로 압축할 수 있습니다 @F.

echo "---";perl  -aF"\t" -ne 'if ($.==1){@c=@F; chomp($c[$#c]);}else {
 print "\n";for ($i=0;$i<=$#F;$i++){print "$c[$i]: $F[$i]\n";}}' input_text.txt

답변4

csvjson -t file | yq -y .

원본 데이터의 필드가 탭으로 구분되어 있다고 가정하면 다음을 사용합니다 csvjson.csvkit툴킷) 데이터를 JSON 형식으로 변환합니다. 파서 yq(에서https://kislyuk.github.io/yq/)은 JSON을 YAML로 트랜스코딩하는 데 사용됩니다.

질문의 데이터가 주어지면 최종 출력은 YAML 문서가 됩니다.

- your-email: [email protected]
  your-order-id: 12345
  PayPal-transaction-id: 54321
  your-first-name: sooky
  your-second-name: spooky
- your-email: [email protected]
  your-order-id: 23456
  PayPal-transaction-id: 23456
  your-first-name: kiki
  your-second-name: dee
- your-email: [email protected]
  your-order-id: 34567
  PayPal-transaction-id: 76543
  your-first-name: cheeky
  your-second-name: chappy

질문에서 예상되는 출력은 여러 개의 중복 키가 있는 단일 섹션이므로 거의 의미가 없다는 것을 알았습니다(키의 값은 동일한 키의 후속 인스턴스로 덮어쓰기됨). 따라서 나는 이것을 무시하고 대신 중복 키가 없는 문서를 사용하기로 결정했습니다(위 문서에는 세 개의 개체 목록이 포함되어 있습니다).

대신에 csvjson -j file다음을 사용할 수 있습니다.

mlr --itsv --ojson --jlistwrap cat file

mlr...밀러( )를 사용합니다.https://miller.readthedocs.io/en/latest/탭으로 구분된 입력을 JSON으로 변환합니다.

대신에 yq -y .다음을 사용할 수 있습니다.

yj -jy

... yj다음에서 사용https://github.com/sclevine/yjJSON을 YAML로 변환합니다.

TSV-->JSON 및 JSON-->YAML 트랜스코딩 언급된 네 가지 도구를 조합하면 궁극적으로 동일한(또는 동등한) 결과를 얻을 수 있습니다.

관련 정보