awk는 쉘 문자열(변수)에 대한 필드 식별자도 사용할 수 있나요?

awk는 쉘 문자열(변수)에 대한 필드 식별자도 사용할 수 있나요?

글쎄, 내가 시도한 방식으로는 분명히 불가능합니다.

이 대안을 얻을 수 있습니다술집그러나 결과 문자열은 유효합니다.

#!/bin/bash

path1=/usr/tmp/foo/bar/baz

awk -F/ '{print $5}' <<< "$path1"

지금까지는 괜찮습니다. 하지만 <<<연산자와 악명 높은 파이프를 사용하고 싶지 않으면 echo | ...어떻게 해야 합니까 ? 간단히 말해서, 내가 하고 싶은 것은 path1지시문을 변수로 전달하는 것 입니다.-v pa="$path1"그리고다음 -F/과 같은 필드 구분 기호 및 필드 식별자를 사용하여 $5구문 분석됩니다 .awk내부 pa값이 다음과 같은 변수외부 path1쉘 변수. "사내"에서도 가능 awk합니까 ?

답변1

-v옵션이나 인수 var=value의 문제점 awk은 ANSI C 이스케이프 시퀀스(예: \n, \b...)가 확장되어(그리고 GNU awk4.2 이상 에서는값이 로 시작 @/하고 끝나는 경우 /정규식 유형의 변수로 처리됩니다.).

또 다른 방법은 다음을 사용 ARGV하거나 ENVIRON awk배열하는 것입니다.

awk -F / 'BEGIN{$0 = ARGV[1]; print $5}' "$path1"

또는:

export path1
awk -F / 'BEGIN{$0 = ENVIRON["path1"]; print $5}'

또는:

path1="$path1" awk -F / 'BEGIN{$0 = ENVIRON["path1"]; print $5}'

이제 원하는 것이 쉘 변수를 분할하는 것이라면 이것이 필요하지 않을 수도 있습니다 awk.

모든 POSIX 쉘에서:

IFS=/; set -f
set -- $path1
printf '%s\n' "$5"

답변2

pa배열로 나눌 수 있습니다

awk -F'/' -v pa=$path1 'BEGIN{split(pa, arr, FS); print(arr[5]); exit}'

답변3

awk환경 변수를 스크립트/명령에 전달하는 방법에는 여러 가지가 있습니다 .

방법 1

이로 인해 쉘은 $path1명령을 실행하기 전에 변수를 확장합니다 awk.

$ echo $path1
/usr/tmp/foo/bar/baz
$ awk -F'/' 'END{a="'$path1'"; split(a,arr,FS); print(arr[5])}' /dev/null
bar

방법 #2

환경을 통해. 의 변수는 awk 변수인 a.

$ awk -F '/' 'END{split(a,arr,FS); print(arr[5])}' a=$path1 /dev/null
bar

방법 #3

awk변수를 명시적 으로 전달하려면 스위치를 사용하십시오 -v.

$ awk -F'/' -v a=$path1 'END{split(a,arr,FS); print(arr[5])}' /dev/null
bar

디버그

set -x무슨 일이 일어나고 있는지 확인하기 위해 이러한 명령을 실행하기 전에 설정하여 셸의 자세한 정보를 활성화할 수 있습니다 . 방법 #2를 예로 들어보겠습니다.

$ set -x
$ awk -F '/' 'END{split(a,arr,FS); print(arr[5])}' a=$path1 /dev/null
+ awk -F / 'END{split(a,arr,FS); print(arr[5])}' a=/usr/tmp/foo/bar/baz /dev/null
bar

위는 set -xawk 라인 이후의 실행을 보여줍니다. 실행 시간에 따라 실행 시간 변수 a의 값이 $path1확장된 것을 확인할 수 있습니다 .

또 다른 예는 이번에는 방법 #1입니다.

$ awk -F'/' 'END{a="'$path1'";split(a,arr,FS); print(arr[5])}' /dev/null
+ awk -F/ 'END{a="/usr/tmp/foo/bar/baz";split(a,arr,FS); print(arr[5])}' 
bar

$path1여기서는 셸이 실행되기 전에 변수를 확실히 확장하는 것을 볼 수 있습니다 awk.

답변4

어때요?

basename "$(dirname "$path1")"

또는 쉘이 프로세스 대체를 지원하고 다음을 사용해야 하는 경우 awk:

awk -F'/' '{print $5}' <(printf '%s\n' "$path1")

관련 정보