awk: 고정 길이 파일에서 여러 하위 문자열을 선택하는 방법은 무엇입니까?

awk: 고정 길이 파일에서 여러 하위 문자열을 선택하는 방법은 무엇입니까?

나는 검색하고 검색했지만 실제로 이 질문에 대한 답을 찾지 못했습니다. 아이디어는 dat 파일이 있고 그 안에 일부 데이터 필드가 필요하다는 것입니다.

샘플 데이터(test.dat)

50DI 20170510144200Mike   Tester       BL0004992000US
50ELI20170509145200Roy    Developer    BL0003400020MX

따라서 두 번째 데이터 필드가 위치 3(DI 또는 ELI)에서 시작하고 길이가 3이 되도록 하려면 다음을 수행합니다.

awk '{print substr($0,3,3)}' test.dat

하지만 원본 dat 파일에서 여러 데이터 필드를 가져오는 방법을 모르겠습니다. 내가 생각해낸 것 중 가장 좋은 것은 이것이다(이전 버전을 복사하면서 편집됨).

#!/bin/bash

for i in {1..1}; do
    a=$(awk '{print substr($0,0,2)}' test.txt)
    b=$(awk '{print substr($0,20,7)}' test.txt)
    echo $a, $b
done

결과는

50 50, Mike Roy

바꾸다

50, Mike
50, Roy

이 예는 약간 기본적이지만 아이디어는 동일합니다. awk를 사용하여 여러 하위 문자열을 얻는 방법은 무엇입니까? (면책조항: 저는 awk와 결혼한 것이 아닙니다. 단지 더 나아지려고 노력하는 것뿐입니다. 다른 솔루션도 높이 평가됩니다!)

답변1

awk실제로 고정 너비를 원한다고 가정하고 GNU를 사용하면 다음과 같습니다.

awk -v FIELDWIDTHS='2 17 7' -v OFS=', ' '{ print $1, $3 }' test.dat

그리고 bash:

while read -r line; do
    printf '%s, %s\n' "${line:0:2}" "${line:19:7}"
done <test.dat

약간 현대적 sed입니다.

sed 's/^\(..\).\{17\}\(.\{7\}\).*/\1, \2/' test.dat

그리고 perl:

perl -lpe '$_ = join ", ", unpack "A2x17A7"' test.dat

위의 경우에 대해 다음을 출력합니다.

50, Mike
50, Roy

답변2

어때요 cut?

cut -c1-2,20-26 --output-delimiter ', ' test.dat
50, Mike
50, Roy

답변3

짧은sed방법:

sed -En 's/^(.{2}).{17}(\S+).*/\1, \2/gp' test.dat

산출:

50, Mike
50, Roy

관련 정보