다음 형식의 탭으로 구분된 값이 있는 파일이 있습니다.
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 트랜스코딩 언급된 네 가지 도구를 조합하면 궁극적으로 동일한(또는 동등한) 결과를 얻을 수 있습니다.