awk: 코드가 하위 문자열을 수집하는 방법

awk: 코드가 하위 문자열을 수집하는 방법

일반적인 질문이 아니더라도 양해해 주시기 바랍니다. n번째 필드 구분 기호 앞에 있는 하위 문자열을 가져오는 코드를 사용하고 있습니다.

echo '123-321-333-111-235'| awk -F"-" '
BEGIN {n=3}
{for(i=1;i<=n;++i)  
k = k (k=="" ? "" : FS) $i; 
print(k) 
}'

이것은

123-321-333

이 줄이 어떻게 작동하는지 이해하지 못합니다 k = k (k=="" ? "" : FS) $i;. 나를 혼란스럽게 하는 것은 k=k삼항 연산자 주변의 부분입니다. $i내 질문은 단지 설명을 듣기 위한 것입니다

답변1

echo '123-321-333-111-235' |
awk -F'-' -v n=3 '
  {
     for( i=1; i<=n; ++i )
        k = k (k == "" ? "" : FS) $i
     ;
     print k
  }
'

루프를 for3번 실행합니다:

i=1:

 k is empty, $i -> $1 -> 123

 k <= empty ( empty == empty ? empty : "-" ) 123

 k <= empty empty 123

 k <= "123"

i=2:

 k is "123", $i -> $2 -> 321

 k <= "123" ( 123 == empty ? empty : "-" ) 321

 k <= "123" "-" "321"

 k <= "123-321" due to the implicit concatenation property of awk strings

i=3:

 k is "123-321", $i -> $3 -> 333

 k <= "123-321" ( 123-321 == empty ? empty : "-" ) 333

 k <= "123-321" "-" "333"

 k <= "123-321-333"

 This value of k is now sent to stdout.
 STOP.

또는 다음을 수행할 수 있습니다.

n=3

echo '123-321-333-111-235' | sed -ne "s/-/\n/$n;P"

echo '123-321-333-111-235' | perl -F- -lane "\$, = '-'; print @F[0..$n-1]"

( 
   var='123-321-333-111-235'
   set -f; IFS='-'; set -- $var

   for((i=1;i<=$n;i++))
   do
      v=${v-}${v:+"$IFS"}$1
   done
   echo "$v"

   # or, alternatively:
   N=$#
   while case $# in `expr $N - $n` ) break ;; esac; do
     V=${V-}${V:+"$IFS"}$1
     shift
   done
   echo "$V"
)

var='123-321-333-111-235'
FS='-'; # field separator provided here
fields=$(yes "[^$FS]*$FS" | head -n $n | tr -d '\n')
result=`expr "$var$FS" : "\($fields\)"`
echo "${result%?}"

답변2

해당 항목이 있는 경우 k = k $i현재 처리되는 각 반복 필드의 끝에 추가됩니다 k(따라서 123321333을 얻게 됩니다).

이 있는 경우 k = k FS $i-123-321-333을 받게 됩니다.

awk가 $1을 처리할 때 k가 비어 있으므로 삼항 if는 처음에 대시가 없는지 확인하므로 삼항 if는 ""를 반환합니다.

관련 정보