awk 및 Windows 경로 백슬래시 이스케이프 문자

awk 및 Windows 경로 백슬래시 이스케이프 문자

여기경로에서 기본 이름을 추출하는 좋은 방법을 찾았습니다 awk.

awk 'BEGIN{ var="Z:\201708021541\file name with spaces.123"; n=split(var,a,/\//); print a[n]}'

그러나 백슬래시의 경우 문자가 이스케이프된 것처럼 보이기 때문에 작동하지 않습니다. 예를 들어 위의 출력은 다음과 같습니다.

Z:�708021541
            ile name with spaces.123

이제 awk를 우회할 수 있는 방법이 있나요? 경로가 파일에 나열되어 있고 escape하기 위해 모든 것을 전처리할 수 없습니다(원하지 않음). \그래서 awk에게 "이스케이프하지 마세요"라고 말할 수 있는 방법이 있는지 궁금합니다.

답변1

백슬래시가 포함된 Windows 경로 이름의 파일 이름 부분을 찾으려고 한다고 가정해 보겠습니다.

pathname='Z:\201708021541\file name with spaces.123'
filename=$(basename "${pathname//\\//}")

printf '%s\n' "$filename"

이것은 인쇄됩니다

file name with spaces.123

에서 실행 중인 경우 bash.

매개변수 대체는 ${pathname//\\//}값의 모든 백슬래시를 슬래시로 대체합니다 $pathname. 이는 표준 basename유틸리티가 이를 처리할 수 있음을 의미합니다. 유틸리티 basename는 경로의 시작 부분에 대해 신경 쓰지 않습니다 Z:(디렉토리 이름이라고 생각함).

또는 (더 짧고 이식성이 더 높음):

pathname='Z:\201708021541\file name with spaces.123'
filename=${pathname##*\\}

printf '%s\n' "$filename"

여기에서는 ${pathname##*\\}마지막 백슬래시 앞의 모든 내용이 제거됩니다 $pathname. 이 매개변수 대체는 표준이지만 첫 번째 변형에 사용된 매개변수 대체는 일부 쉘에서만 작동합니다.


사용 awk:

printf '%s\n' "$pathname" | awk '{ sub(".*\\\\", "", $0); print }'

이러한 네 개의 백슬래시는 이유 때문에 두 개의 백슬래시로 각각 한 번씩 이스케이프됩니다.

사용 sed:

printf '%s\n' "$pathname" | sed 's/.*\\//'

awk그리고 sed솔루션은 정확히 같은 방식으로 작동합니다. 마지막 백슬래시까지의 모든 항목을 빈 문자열로 바꿉니다.

관련 정보