awk를 사용하여 정확한 일치 만들기

awk를 사용하여 정확한 일치 만들기

awk를 사용하여 정확한 일치를 수행하는 방법이 궁금합니다.

예를 들어

$ cal 09 09 2009
   September 2009
Su Mo Tu We Th Fr Sa
   1  2  3  4  5
6  7  8  9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30



$ cal 09 09 2009 | awk '{day="9"; col=index($0,day); print col }'
17
0
0
11
20
0
8
0

위 명령이 문자열/숫자 "9"를 포함하는 모든 줄의 인덱스 번호를 출력하는 것을 볼 수 있듯이, 위 cal 출력의 4번째 줄에서만 awk 출력 인덱스 번호를 만드는 방법이 있습니까??? 훨씬 더 우아한 솔루션이 될 수 있습니까?

나는 awk를 사용하여 cal 명령을 사용하여 요일 이름을 가져오고 있습니다. 전체 코드 줄은 다음과 같습니다.

     $ dayOfWeek=$(cal $day $month $year | awk '{day='$day'; split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", array); column=index($o,day); dow=int((column+2)/3); print array[dow]}')

위 코드의 문제점은 일치하는 항목이 여러 개 발견되면 여러 결과를 얻는 반면 하나의 결과만 출력하기를 원한다는 것입니다.

감사해요!

답변1

다음 한 줄만 grep출력 할 수 있습니다 .cal

$ cal 09 09 2009 | grep -E '(^9 | 9 | 9$)' | awk ...

grep은 다음 중 하나와 일치합니다.

  • 9 다음에 줄 시작 부분에 공백이 옵니다.
  • 공백으로 둘러싸인 9
  • 줄 끝에 9가 붙는 공백입니다.

당신에게 있어서는 어떤가요?

답변2

나는 이것을 다음과 같이 할 것입니다

dayOfWeek="$(cal $month $year |
             awk -v day=$day \
                'BEGIN {split("Sunday Monday Tuesday Wednesday Thursday Friday Saturday", days)}
                 NR > 2 {for (i = 1; i <= NF; i++) {if ($i == day) {print days[i]}}}')"

여기서는 배열 BEGIN을 설정하기 위해 처음에 실행됩니다 days. 다른 패턴은 2행 이상(헤더 건너뛰기)에서 트리거되고 를 찾을 때까지 열을 단계별로 살펴본 day다음 열 번호를 사용하여 요일을 조회합니다. $in은 awk필드 참조 연산자입니다. $1첫 번째 필드 와 마찬가지로 $n의 값으로 필드 번호가 매겨집니다 n. 또한 줄 시작 부분에 할당된 $day를 쉘에서 스크립트로 전달합니다 awk. NR레코드 번호(줄 번호)입니다. NF행의 필드 수입니다. ( RS및 를 FS각각 설정하여 레코드와 필드를 구분하는 항목을 각각 변경할 수 있습니다 .)

(백슬래시-개행 문자와 파이프 뒤의 개행 문자 |는 단지 명확성을 위한 것이며 스크롤되지 않도록 하기 위한 것입니다.~도많이.)

이번에는 테스트를 거쳤습니다.

답변3

이 페이지의 스크립트가 바로 그런 일을 합니다

http://www.computing.net/answers/unix/find-the-day-of-week-using-awk/5243.html

답변4

이것을 시도해 보십시오:

cal 09 2009 | awk -v "num=9" '
    BEGIN {
        OFS="\t";
        day=" ?[^0-9]" num "([^0-9]|$)"
    }
    NR==2 {dow = $0}
    $0 ~ day {
        col=match(" " $0, day);
        print $0, col, substr(dow,col,2)
    }'

한 줄에 모두 :

cal 09 2009 | awk -v "num=9" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, col, substr(dow,col,2) }'

데모:

$ for i in {1..30}; do cal 09 2009 | awk -v "num=$i" 'BEGIN {OFS="\t"; day=" ?[^0-9]" num "([^0-9]|$)"} NR==2 {dow = $0} $0 ~ day {col=match(" " $0, day); print $0, num, col, substr(dow,col,2) }'; done
       1  2  3  4  5    1       7       Tu
       1  2  3  4  5    2       10      We
       1  2  3  4  5    3       13      Th
       1  2  3  4  5    4       16      Fr
       1  2  3  4  5    5       19      Sa
 6  7  8  9 10 11 12    6       1       Su
 6  7  8  9 10 11 12    7       4       Mo
 6  7  8  9 10 11 12    8       7       Tu
 6  7  8  9 10 11 12    9       10      We
 6  7  8  9 10 11 12    10      13      Th
 6  7  8  9 10 11 12    11      16      Fr
 6  7  8  9 10 11 12    12      19      Sa
13 14 15 16 17 18 19    14      4       Mo
13 14 15 16 17 18 19    15      7       Tu
13 14 15 16 17 18 19    16      10      We
13 14 15 16 17 18 19    17      13      Th
13 14 15 16 17 18 19    18      16      Fr
13 14 15 16 17 18 19    19      19      Sa
20 21 22 23 24 25 26    21      4       Mo
20 21 22 23 24 25 26    22      7       Tu
20 21 22 23 24 25 26    23      10      We
20 21 22 23 24 25 26    24      13      Th
20 21 22 23 24 25 26    25      16      Fr
20 21 22 23 24 25 26    26      19      Sa
27 28 29 30             28      4       Mo
27 28 29 30             29      7       Tu
27 28 29 30             30      10      We

Mohamed가 연결한 스크립트의 개선 사항은 다음과 같습니다.

cal 09 2009 | awk -v "d=9" 'NR==2 {split($0, dow)} NR == 3 {print $0, d, dow[7 - ($NF + 35 - d) % 7]}'

head이나 tail많은 진술이 필요하지 않습니다 if.

관련 정보