시스템이 awk에서 cp를 호출하도록 전달된 변수에서 공백 등을 이스케이프 처리하는 방법

시스템이 awk에서 cp를 호출하도록 전달된 변수에서 공백 등을 이스케이프 처리하는 방법

이 문제에는 간단한 이스케이프 문자를 어렵게 만들기에 충분한 복잡성이 있습니다. 나는 bash 스크립트를 가지고 있으며 그 중 대부분에는 세미콜론으로 구분된 파일을 읽는 awk 스크립트가 포함되어 있습니다. 이 텍스트 파일에서 필드 중 하나는 일부 JPEG에 대한 디렉터리 경로입니다. JPEG를 다른 곳에 복사하고 싶지만 원래 디렉토리 경로에 공백이 있습니다(그리고 손상을 일으킬 수 있는 다른 문자열도 있을 수 있습니다). 문제의 디렉토리를 작은 따옴표로 묶을 수 없습니다. 왜냐하면 awk 인터프리터가 중지되고 큰 따옴표를 사용하면 awk의 리터럴 문자열로 변환되기 때문입니다.

gawk 4.1.1을 사용하고 있습니다. 내가 달성하려는 작업에 대한 몇 가지 awk 코드는 다음과 같습니다.

imageDirectory = $1;
cpJpegVariable="cp -r " imageDirectory " assets";
#screws up if imageDirectory has spaces and other naughty characters
system(cpJpegVariable);

답변1

당신은 그것을 사용할 수 있습니다 :

awk '...
    cpJpegVariable="cp -r '\''" imageDirectory "'\'' assets";
    ...'

( '이스케이프는 필수가 아니지만 awk'\''이스케이프는 필수입니다.) 따라서 awk변수가 확장 되면 cpJpegVariable다음과 같습니다.

cp -r 'file_contain space' assets

이렇게 하면 '자신을 제외한 모든 특수 문자와 관련된 문제를 피할 수 있습니다. 작은따옴표 문자가 포함될 수 있는 경우 imageDirectory이스케이프 문자를 사용할 수 있습니다 gsub(). 예:

awk '{gsub("'\''","'\''\"'\''\"",imageDirectory)}1'

답변2

Awk 변수를 전달하면체계, 인용하려면 쉘이 필요합니다.

function quote(str,   d, m, x, y, z) {
  d = "\47"; m = split(str, x, d)
  for (y in x) z = z d x[y] d (y < m ? "\\" d : "")
  return z
}

예:

system(sprintf("cp -r %s assets", quote($1)))

원천

답변3

외부 명령 실행은 awk가 아닌 쉘용입니다.

while read image_dir __; do
    cp -r "$image_dir" assets
done < file

관련 정보