2016-08-01 2 views
1

달의 N 번째 영업일을 얻으려는 해답을 this unix.com thread에 게시하면 다음 코드를 사용하여 매월 16 일의 영업일을 보냈지 만 작동하지 않습니다.n 번째 영업일을 얻으려면 유닉스 쉘 스크립트

currCal=`/usr/bin/cal` 
BUSINESS_DAYS=`echo $($currCal|nawk 'NR>2 {print substr($0,4,14)}' |tr "\n" " ")` 

오류 때 실행이됩니다

nawk :. 소스 라인 (1) 상황의 구문 오류 NR> 2- {인쇄 >>> SUBSTR (시험이다 < < < SH, 4, 14)} nawk : 소스 라인 1

에서 불법 성명 나는 구문 오류가 발생, 스크립트 이름으로 $0 소요 같은데요. 도와주세요.

+0

명령에 표시된대로 ''NR> 2 {print substr ($ 0,4,14)} ''가 _single_ 따옴표 안에 있습니다. 이 오류 메시지는 _different_ 명령이 실행되었음을 나타내며, nawk에 대한 인수는 _double_ 따옴표 안에 있지만 _single_ 따옴표에는 없습니다. – John1024

+0

@ John1024 John 감사합니다. 나는이 BUSINESS_DAYS ='$ ($ currCal | nawk "NR> 2 {print substr ($ 0,4,14)}"| tr "\ n" "")'같은 오류를 시도했다. – Pat

+0

다시 작은 따옴표를 사용해야하는 경우 awk 인수를 큰 따옴표로 묶어 사용합니다. – John1024

답변

2

위와 관련하여 몇 가지 문제가있는 것으로 보입니다.

먼저, 나는이 당신이 게시 한 된 오차 nawk 얻기 위해 @ 그 John1024에 동의, 당신은 실제로 실행해야합니다

BUSINESS_DAYS=`echo $($currCal|nawk "NR>2 {print substr($0,4,14)}" |tr "\n" " ")` 

을 nawk 스크립트를 큰 따옴표로.

또한 nawk 오류를 해결하면 currCal을 사용하는 방법에 문제가 발생할 것입니다. 변수에 cal 명령의 실제 출력을 가져 오지만 echo이 아닌 파이프 또는 이와 유사한 변수 값 앞에 | 앞에있는 변수 값 (즉, cal의 출력)을 명령으로 사용하고 있습니다.

다른 서브 쉘 (바깥 쪽의``s) 내의 서브 쉘 명령 ($() 부분)의 결과에 echo을 사용하는 이유에 대한 추가 질문이 나타납니다.

마지막으로 위에 표시된 두 줄은 당월의 영업일 목록을 BUSINESS_DAYS 변수로 가져옵니다. 그들은 16 일을 출력/저장하지 않습니다. 당신이 정말로 현재 달의 달력을 캐시 필요합니다

: 다음 호출 중 하나를 할 수 있습니다 (또한 지속적으로 $() 서브 쉘 구문을 사용하여 변경) 고려 사항으로 위의 모든 촬영

복수의 날을 당겨 :

currCal="$(/usr/bin/cal)" 
BUSINESS_DAYS="$(echo "${currCal}" | \ 
        nawk 'NR>2 {print substr($0,4,14)}' | \ 
        tr "\n" " ")" 

DAY=16 
DAYTH_DAY="$(echo "${BUSINESS_DAYS}" | nawk -v "day=${DAY}" '{ print $day }') 

을이 단지 1과 수행의 경우 :

,543,

한 가지 더 알아 두십시오 : awk (/ nawk)에서 완전히 완료되면 여기 처리가 단순화 될 수 있지만 이미 선택한 기본 프레임 워크를 고수하고 싶습니다.주석의 요청에 따라


업데이트 :

순수 POSIX의 AWK 버전 :

DAY=16 
DAYTH="$(cal | awk -v "day=${DAY}" ' 
      (NR < 3) { next ; } 
      /^.[0-9 ]/ { $1="" ; } 
      /^/|| (NF == 7) { $NF="" ; } 
      { hold=hold $0 ; } 
      END { split(hold,arr," ") ; print arr[day] ; }')" 

예, 단순화 된 의견의 문제입니다, 나는 확신 누군가가 이것을보다 간결하게 만들 수 있습니다. 이것이 어떻게 작동하는지 설명 :

/^.[0-9 ]/ { $1="" ; } 

의 경우 : 일요일에 날짜가 주 동안

(NR < 3) { next ; } 

, 즉 일요일의 날짜를 트림 :

는 칼 출력의 헤더를 건너 뛰기 일주일 후 (일주일의 첫째 주) 또는 주 (전체 7 일간) : 해당 주간 토요일 날짜를 자르십시오.

선 일단

2,063,210 만 hold로 카레, 평일의 날짜가 :

END { split(hold,arr," ") ; print arr[day] ; }')" 
+0

@ j-cordasco 자세한 설명을 주셔서 감사합니다. 나는 비즈니스 로직을 찾기위한 논리를 찾고 있었고 그 중 하나를 발견했다. 내 질문에 말했다. 거기에서 로직이 노크와 함께 있다는 것을 알게되었으므로 다른 특별한 이유는 없습니다. John과 당신에 의해 말했듯이, 나는 awk 코드를 바꿀 수있다. 그러나 나는 이것을 "awk"로 바꾸는 데 다시 당신의 도움이 필요하다. 저 좀 도와 주 시겠어요? – Pat

0

번호 :

{ hold=hold $0 ; } 

을 끝에서, 그래서 우리는 N 번째 일을 잡을 수 공간에 hold 분할 awk, 단지 소프트웨어 도구 :

set -- $(cal -h | rev | cut --complement -b-5,20- | rev | tail -n +3) ; \ 
shift 15 ; echo $1 

출력 :

22 

cal의 출력 때문에 구문 분석 할 수 까다 롭다는 :

  1. 이 오른쪽으로 정렬합니다.
  2. 공백으로 구분됩니다.
  3. 한 자리 또는 두 자리 날짜는 두 개 또는 하나의 구분 된 공백을 의미합니다.
  4. 월의 첫 번째 날에 더 많은 선행 공백이 있습니다.
  5. -h 옵션을 사용하지 않으면 구문 분석이 제대로 작동하지 않습니다 ('오늘'강조 표시 해제).
관련 문제