awk를 사용하여 파일 형식 지정

awk를 사용하여 파일 형식 지정

내 입력 파일에는 다음 형식의 데이터가 포함되어 있습니다.

1503668542862176    manager=10001|Bounced=999|Analyst=10004|Business Analyst=10005|Programmer=10003
1552024948590636    manager=10001|Bounced=999|Analyst=10004
1551728916565460    Bounced=999|Analyst=10004
1553617087089790    Analyst=10004
1538058487418963    manager=10001|Architect=10002|Analyst=10004

key=value각 쌍을 큰따옴표로 묶고 "key"="value"다음으로 바꿔야 하는 두 번째 열을 변환해야 합니다 |.,awk

1503668542862176    "manager"="10001","Bounced"="999","Analyst"="10004","Business Analyst"="10005","Programmer"="10003"
1552024948590636    "manager"="10001","Bounced"="999","Analyst"="10004"
1551728916565460    "Bounced"="999","Analyst"="10004"
1553617087089790    "Analyst"="10004"
1538058487418963    "manager"="10001","Architect"="10002","Analyst"="10004"

답변1

$ sed -e 's/|/","/g' -e 's/=/"="/g' -e 's/\t/\t"/' -e 's/$/"/' input.txt

이는 다음을 수행합니다.

  • |다음 으로 대체,
  • =다음 으로 대체"="
  • 첫 번째 탭 정지를 다음으로 교체\t"
  • "a 및 줄 끝 추가

가장 쉬운 방법 awk은 필드 구분 기호를 변경하는 것입니다.

$ awk -v FS="|" -v OFS='","' '{$1=$1}1' \
  | awk -v FS="=" -v OFS='"="' '{$1=$1}1'\
  | awk -v FS="\t" '{print $1,"\""$2"\""}' input.txt

답변2

sed를 사용하세요:

sed -e 's/|/","/g;s/=/"="/g;s/ /"/4;s/$/"/g' file

1503668542862176   "manager"="10001","Bounced"="999","Analyst"="10004","Business Analyst"="10005","Programmer"="10003"
1552024948590636   "manager"="10001","Bounced"="999","Analyst"="10004"
1551728916565460   "Bounced"="999","Analyst"="10004"
1553617087089790   "Analyst"="10004"
1538058487418963   "manager"="10001","Architect"="10002","Analyst"="10004"

답변3

GNU awk(일반적으로 모든 표준 Linux 배포판에서 사용 가능)에 액세스할 수 있는 경우 함수와 함께 하위 표현식을 사용할 수 있습니다 gensub() .

< input_data awk -- '{gsub("\\|", ","); print gensub("([[:alpha:]][^=]*)=([^,]+)", "\"\\1\"=\"\\2\"", "g")}'

|키-값 쌍 구분 기호로만 나타난다 고 가정하면 gsub()각 값은 먼저 |in 으로 변환된 ,다음 gensub()함수가 나머지 작업을 수행합니다.

POSIX awk를 사용해야 하는 경우에도 일련의 (정말 어색한...) 단일 스크립트를 사용하여 동일한 결과를 얻을 수 있습니다 gsub().

< input_data awk -- '{gsub("=", "\""); gsub("([[:alpha:]][^\"]*)", "\"&\"="); gsub("\"[^|]*", "&\""); gsub("\\|", ","); print;}'

분석( awk스크립트 부분만):

{
    gsub("=", "\"");
    gsub("([[:alpha:]][^\"]*)", "\"&\"=");
    gsub("\"[^|]*", "&\"");
    gsub("\\|", ",");
    print;
}

첫 번째는 gsub()각각을 =a 로 대체하여 "다음 여러 s 에 대한 길을 닦고 gsub(), 첫 번째 것은 첫 번째 키까지(포함하지 않음) 키를 찾고 ", 전체 문자열을 선행 "+ 발견된 키 + Trailing 으로 대체합니다 "=. 두 번째는 (초기 )부터 첫 번째(있는 경우)까지(포함하지 않음 ) gsub()값을 찾고 해당 문자열을 그 자체와 후행 문자열로 바꿉니다 ."=|"

기본적으로 두 번째 솔루션은 "보조 키-값 구분 기호 역할을 하므로 키나 값에 표시되지 않아야 합니다.

최종 솔루션은 모두 첫 번째 솔루션을 gsub()대체합니다 .|,

답변4

awk 명령을 통해 완료됨

주문하다:

awk '{gsub(/\|/,",",$0);print $0}' filename | awk '{$2="\""$2;print $0}'| awk '{gsub(/\=/,"\"=\"",$0);print $0}'| awk '{gsub(/\,/,"\",\"",$0);print $0}'| awk '{$NF=$NF"\"";print $0}'

산출

 awk '{gsub(/\|/,",",$0);print $0}' filename| awk '{$2="\""$2;print $0}'| awk '{gsub(/\=/,"\"=\"",$0);print $0}'| awk '{gsub(/\,/,"\",\"",$0);print $0}'| awk '{$NF=$NF"\"";print $0}'

1503668542862176 "manager"="10001","Bounced"="999","Analyst"="10004","Business Analyst"="10005","Programmer"="10003"
1552024948590636 "manager"="10001","Bounced"="999","Analyst"="10004"
1551728916565460 "Bounced"="999","Analyst"="10004"
1553617087089790 "Analyst"="10004"
1538058487418963 "manager"="10001","Architect"="10002","Analyst"="10004"

관련 정보