awk + 깨끗한 경로에 붙여넣으시겠어요?

awk + 깨끗한 경로에 붙여넣으시겠어요?

.cshrc여러 컴퓨터의 초기화 파일에서 이 코드를 본 적이 있습니다. 나는 경험했다몇 가지 이상한 튜토리얼그것이 어떻게 작동하는지 이해하려고 노력하지만 여전히 해독할 수 없습니다.

setenv PATH `echo $PATH | awk 'NF&&\\!x[$0]++' RS='[:|\n]' | paste -sd:`

그것은 무엇을 합니까?

답변1

백슬래시는 나에게 적합하지 않지만 다음과 같이 설명할 수 있습니다.

echo "$PATH" | awk 'NF && !x[$0]++' RS='[:|\n]'

레코드 구분 기호( RS)는 ":", "|" 문자 및 개행 문자 중 하나로 설정됩니다. $PATH일반적으로 요소가 ":"으로 구분된 한 줄입니다. 이렇게 하면 awk는 경로가 ":"으로 구분되지 않은 것처럼 작동하지만 각 경로는 자체 줄에 있습니다.

NF빈 줄( NF == 0)이 무시됨을 나타냅니다. x경로로 인덱싱된 연관 배열입니다. 0보다 크면 !x[$0]++"행"을 무시함을 나타냅니다. 결과적으로 각 행은 한 번만 출력됩니다. x[$0]첫 번째 실행 중에 증가하므로 x[$0]후속 실행에서는 !x[$0]거짓입니다 .

이 예에서는 마지막 행 이후의 모든 요소가 처리되는 빈도를 보여줍니다.

echo "a:b:a:c:a:b" |
  awk 'NF && !x[$0]++;END {for (var in x) print var ": " x[var]}' RS='[:|\n]'
a
b
c
a: 3
b: 2
c: 1

답변2

설명한대로하우케여기서의 목적은 $PATH변수에 고유한 요소만 포함시키는 것입니다.

그러나 이것은 이식 가능한 awk 스크립트가 아니며 RS일반적으로 정규 표현식이 아닌 단일 문자로 제한됩니다. 보다 이식성이 뛰어난 대안은 다음과 같습니다.

setenv PATH `printf "%s" "$PATH" | awk '{ sub("/$","") }; x[$0]++ < 1' RS=: | paste -s -d : -`

tcsh에서 gawk 및 nawk를 사용하여 테스트되었습니다.

참고할 몇 가지 사항이 있습니다.

  • 불필요한 줄바꿈을 방지하는 데 사용합니다 printf.
  • , 이는 !값이 1보다 작은지 확인하여 tcsh에 대한 기록 확장을 대체할 수 있음을 의미합니다.
  • 종료 경로 구분 기호가 제거됩니다 sub().

관련 정보