수정하여 파이프라인으로 구분된 필드를 재정렬합니다.

수정하여 파이프라인으로 구분된 필드를 재정렬합니다.

다음 형식의 약 8k 줄로 구성된 Linux 텍스트 파일이 있습니다.

|f_name:x|l_name:x|address:x x|city:x|state:x|zip:x|country:x|ordernumber:x|code:x|downloaded:x|exp:09/2017|ip:x.x.x.x|

다음 형식으로 정렬하고 싶습니다.

ordernumber:x,exp:09/2017,code:x,f_name:x,l_name:x,address:x x,city:x,state:x,zip:x,country:x,ip:x.x.x.x

노트

텍스트의 일부 데이터에 해당 필드에 문제가 있습니다.|address:x x|

이는 끝 앞에 공백이 있다는 의미일 수 있습니다 |address:x x |. 출력에서 ​​하나 이상의 공백을 제거하고 싶습니다.space|

그리고 해당 필드의 데이터에 문제가 있습니다 |exp:09/2017|. 표시된 데이터는 다음과 같습니다 . 월이 단일 숫자인 경우 출력에 표시되도록 |exp:9/2017|추가하고 싶습니다 .009/2017

연도는 다를 수 있습니다.

예:

|f_name:x|l_name:x|address:x x |city:x|state:x|zip:x|country:x|ordernumber:x|code:x|downloaded:x|exp:9/2017|ip:x.x.x.x|

예상 출력:

ordernumber:x,exp:09/2017,code:x,f_name:x,l_name:x,address:x x,city:x,state:x,zip:x,country:x,ip:x.x.x.x**

답변1

암소 비슷한 일종의 영양awk해결책:

awk '{ 
         split($12, a, /[/:]/); 
         if (length(a[2]) == 1) $12=sprintf("%s:%02d/%d", a[1], a[2], a[3]);
         sub(/ *$/, "", $4);
         print $9, $12, $10, $2, $3, $4, $5, $6, $7, $8, $13 
     }' FS='|' OFS=',' file

산출:

ordernumber:x,exp:09/2017,code:x,f_name:x,l_name:x,address:x x,city:x,state:x,zip:x,country:x,ip:x.x.x.x

답변2

일반화하다

나는 Awk 스크립트, Python 스크립트, Bash 스크립트를 작성했는데 각각이 문제를 해결해 줄 것입니다. 그들은 모두 동일한 출력을 생성합니다.

다음은 샘플 데이터입니다(귀하의 질문에서 가져와 파일에 저장 data.csv).

|f_name:x|l_name:x|address:x x|city:x|state:x|zip:x|country:x|ordernumber:x|code:x|downloaded:x|exp:09/2017|ip:x.x.x.x|

다음은 스크립트 실행 결과입니다.

ordernumber:x,exp:09/2017,code:x,f_name:x,l_name:x,address:x x,city:x,state:x,zip:x,country:x,ip:x.x.x.x

다음은 스크립트입니다 awk.

#!/usr/bin/env awk
# transformcsv.awk

# Set the input field-separator (FS) and the output field-separator (OFS)
BEGIN{
    FS="|";
    OFS=",";
}

# Skip empty lines
/^\s*$/ {next;}

# Print lines with the fields reordered as desired
{
   print $9,$12,$10,$2,$3,$4,$5,$6,$7,$8,$13
}

실행 방법은 다음과 같습니다.

awk -f transformcsv.awk data.csv

다음과 같이 한 줄의 코드로 실행할 수도 있습니다.

awk 'BEGIN{FS="|";OFS=",";}/^\s*$/ {next;}{print $9,$12,$10,$2,$3,$4,$5,$6,$7,$8,$13}' data.csv

파이썬

다음은 Python 스크립트입니다.

#!/usr/bin/env python
# -*- coding: ascii -*-
"""transformcsv.py"""

import sys
import csv

# Make a list with the field names in their input order
# NOTE: We padding colums because each row begins
#       and ends with the delimiter `|`
fieldnames = (
    "padding_1",
    "f_name", "l_name", "address", "city", "state", "zip",
    "country", "ordernumber", "code", "downloaded", "exp", "ip",
    "padding_2"
)

# Make a list with the field names in their output order
reordered_fieldnames = (
    "ordernumber", "exp", "code", "f_name", "l_name",
    "address", "city", "state", "zip", "country", "ip"
)

# Read each input row and print out the reordered row
with open(sys.argv[1]) as csvfile:
    reader = csv.DictReader(csvfile, fieldnames=fieldnames, delimiter='|')
    for row in reader:
        print(','.join([row[field] for field in reordered_fieldnames]))

스크립트를 실행하는 방법은 다음과 같습니다.

python transformcsv.py data.csv

불다

노트:이것은 아마도매우큰 파일은 느립니다. 아마도 이것을 사용해서는 안 됩니다. 단지 재미로 포함시킨 것뿐입니다.

Bash 쉘 스크립트는 다음과 같습니다.

#!/usr/bin/env bash
# transformcsv.sh

while read LINE; do
    if [[ -n "${LINE}" ]]; then

    # Extract the field values
    f_name="$(echo "${LINE}" | cut -d'|' -f2)"
    l_name="$(echo "${LINE}" | cut -d'|' -f3)"
    address="$(echo "${LINE}" | cut -d'|' -f4)"
    city="$(echo "${LINE}" | cut -d'|' -f5)"
    state="$(echo "${LINE}" | cut -d'|' -f6)"
    zip="$(echo "${LINE}" | cut -d'|' -f7)"
    country="$(echo "${LINE}" | cut -d'|' -f8)"
    ordernumber="$(echo "${LINE}" | cut -d'|' -f9)"
    code="$(echo "${LINE}" | cut -d'|' -f10)"
    downloaded="$(echo "${LINE}" | cut -d'|' -f11)"
    exp="$(echo "${LINE}" | cut -d'|' -f12)"
    ip="$(echo "${LINE}" | cut -d'|' -f13)"

    # Output the reordered row
    printf \
        "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" \
        "${ordernumber}" "${exp}" "${code}" "${f_name}" "${l_name}" \
        "${address}" "${city}" "${state}" "${zip}" "${country}" "${ip}"

    fi
done < "$1"

실행 방법은 다음과 같습니다.

bash transformcsv.sh data.csv

관련 정보