특정 패턴 사이에서 발생하는 파일의 줄을 특정 길이로 자르는 방법은 무엇입니까?

특정 패턴 사이에서 발생하는 파일의 줄을 특정 길이로 자르는 방법은 무엇입니까?

@TEST 패턴과 활성화="true"> 사이에 있는 줄만 잘라야 하는 파일이 여러 개 있습니다. 일치하는 항목이 있는 경우 @TEST및 사이의 문자열은 enabled="true">50자여야 합니다. 다른 모든 줄은 그대로 두어야 합니다.

예:

@TEST-TC_0010 @TEST RADIUS 계정 서버가 RADIUS 클라이언트로부터 계정 요청 패킷을 수신할 때 계정 응답 메시지를 보내서는 안 되는지 확인하세요."enabled="true">

위의 줄을 아래와 같이 변경해야 합니다.

@TEST-TC_0010@시험RADIUS 계정 서버가활성화="참">

답변1

이 경우 Perl 둘러보기와 함께 grep을 사용할 수 있습니다.

grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile

"(?<=)" 표현식은 일치가 시작되는 지점을 표시하고 "(?=)" 표현식은 일치가 끝나는 지점을 나타냅니다.

".*"는 grep에게 시작 지점과 끝 지점 사이의 모든 항목을 반환하도록 지시합니다.

테스트 입력을 사용하면 위 줄은 157자를 반환합니다.

$ echo "Verify that the RADIUS accounting server should not send the Accounting-Response Message on Receiving the Accounting-Request Packet from the RADIUS Client" | wc -m
157

처음 50자까지만 추가로 자르려면 cut을 사용할 수 있습니다.

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50
Verify that the RADIUS accounting server should no

결과를 파일에 저장하려면 출력을 다른 파일로 파이프해야 합니다. 다음과 같은 것을 사용할 수 있습니다 ...

$ grep -oP '(?<=@TEST ).*(?=\" enabled=\"true\")' inputfile | cut -c1-50 >> outputfile

입력 파일을 덮어쓰는 것은 어느 시점에서 원본 데이터를 사용해야 할 수도 있으므로 개인적으로 권장하는 방법은 아닙니다.

따라서 파일의 다른 모든 항목을 유지하고 활성화="true"인 줄만 잘라야 하는 경우 도구를 awk로 변경해야 합니다.

$ awk  -F'@TEST' '{if (/true/) print substr($3,2,50); else print $0}' inputfile >> outputfile

이 oneliner는 true와 일치하지 않는 모든 줄을 변경 없이 출력합니다. true가 일치하면 줄이 50자로 잘립니다. 다시 한번 말씀드리지만, 결과가 출력 파일로 전달되도록 원본 데이터를 덮어쓰는 것은 권장하지 않습니다.

OP의 질문에 대한 가장 최근 편집 내용을 바탕으로 Beginner가 제공한 출력을 복제하기 위해 awk one-liner를 수정했습니다. 그는 자신의 의견에서 awk가 작동하지 않는다고 언급했습니다. OP가 awk가 작동하지 않는 이유에 대한 자세한 내용을 제공할 때까지 Ubuntu 16.04에서 awk 4.1.3을 사용할 때 다음 줄은 지금까지 자세히 설명한 결과를 반환합니다.

awk  -F'@TEST' '{if (/true/) print "@TEST"$2,"@TEST",substr($3,2,50),"enabled=\"true\">"; else print $0}' inputfile >> outputfile

관련 정보