명절 테이블 만들기

명절 테이블 만들기

이 휴일 목록을 날짜 형식으로 변환하는 스크립트가 필요합니다. 내 입력 파일

MMYYYY CAL_B2K_ID   123456789012345678901234567890  
------ ------------ ------------------------------- 
012016 821          YY      Y      Y      Y      Y  
012016 DC           YY      Y      Y      Y      Y  
022016 DC                Y      Y      Y      Y     
022016 821               Y      Y      Y      Y     
032016 DC               Y      Y      Y      Y      
032016 821              Y      Y      Y      Y      
042016 821           Y      Y      Y      Y         

이제 123456789012345678901234567890은 처음 0이 오면 10이 되고 1은 11을 의미하는 날짜와 같습니다. ...

 1 2 3 4 5 6 7 8 9 10 11 12 13 14............

그래서 나는 Y가 존재할 때마다 첫 번째 줄에서 Y가 1, 2,9,6,3,9 아래에 있다고 가정하여 날짜로 변환하는 스크립트를 만들었습니다.

내 스크립트에서는 21-52열의 각 줄을 잘라서 해당 열이 Y인지 확인하고, 그렇다면 Y가 열 번호 23 아래에 있는 것처럼 날짜로 변환합니다. 그런 다음 (열 번호 - 20)을 뺍니다. 3을 주세요. 그런 다음 연결 연산자를 사용하여 날짜를 만듭니다.

아래는 내 스크립트입니다. 그러나 열 아래에 Y가 없으면 내 var를 공백으로 사용하고 공백도 true 상태가 되는 경우 문제가 발생합니다.

var=echo $f1 | cut -c$i
if [[ "$var"='Y' ]] ;

그리고 내 스크립트는 아래와 같습니다.

 rm f1.txt
 set -x
 while read f1
 do
 for((i=21;i<23;i++));
 do
 var=`echo $f1 | cut -c$i`
 if [[ "$var"='Y' ]] ;
 then
 echo $var
 month=`echo $f1 | cut -c1-2`
 year=`echo $f1 |cut -c3-6`
 date=$(($i-20))
 echo $year"-"$month"-"$date >> f1.txt
 fi
done
done < holiday_india.txt`

var 에 아무것도 없을 때 조건이 true인 경우에 해당되지 않도록 어떻게 할 것인지 알려주세요.

이 스크립트의 단점은 21-52의 각 줄의 모든 열을 Y가 없는 날짜로 변환한다는 것입니다.

이제 명확히 하길 바랍니다.

답변1

좋아요, 아래 스크립트를 복사하고 읽기 쉽도록 들여쓰기를 수정했습니다. (또한 $()나는 그런 방식을 좋아하기 때문에 백틱을 로 변경하고 고정된 파일 이름을 제거했습니다.)

while read f1 ; do
    for((i=21;i<23;i++)); do
        var=$(echo $f1 | cut -c$i)
        if [[ "$var"='Y' ]] ; then
            echo $var
            month=$(echo $f1 | cut -c1-2)
            year=$(echo $f1 |cut -c3-6)
            date=$(($i-20))
            echo "$year-$month-$date"
        fi
    done
done

두 가지가 뛰어납니다.

if [[ "$var"='Y' ]] ; then

이것은 작동하지 않습니다. 등호 주위에 공백이 필요합니다. 시도해보고 무엇을 확인하십시오 [[ X=Y ]] && echo foo.

또한, 여기서

var=$(echo $f1 | cut -c$i)

f1와 같은 내용이 포함되어 있지만 012016 821 YY Y Y Y Y인용되지 않았기 때문에 확장된 다음 공백을 따라 단어가 분할된 후 다음 echo으로 구분된 모든 단어가 인쇄됩니다.하나의공백으로 인해 012016 821 YY Y Y Y Y. 따옴표를 추가하여 문제를 해결할 수 있지만 길이의 하위 문자열을 가져오는 방법 echo "$f1" | cut -c$i도 있습니다."${f1:N:L}"위치에서N. 그러나 인덱스는 0이므로 범위를 $i수정해야 합니다.

그 다음에,

echo "$year-$month-$date"

printf "%04d-%02d-%02d\n" "$year" "$month" "$date"날짜가 항상 두 자리로 인쇄되도록 하고 가능한 변칙적인 값으로부터 보호하기 위해 이를 로 변경할 수 있습니다 $year.

월과 연도 할당은 전체 라인에서 동일하게 유지되므로 외부 루프로 이동하는 것이 좋습니다.

이제 우리는:

while read f1; do
    month="${f1:0:2}"
    year="${f1:2:4}"
    for (( i=20 ; i < 20 + 31 ; i++ )); do
        var="${f1:$i:1}"
        if [[ "$var" = "Y" ]] ; then
            date=$(( $i - 19 ))
            printf "%04d-%02d-%02d\n" "$year" "$month" "$date"
        fi
    done
done

다음을 사용하여 실행하면 출력이 올바르게 보입니다 bash holiday.sh < holiday_india.txt.

2016-01-01
2016-01-02
2016-01-09
2016-01-16
2016-01-23
2016-01-30
2016-01-01

물론 모든 달이 두 배로 늘어난 것 같으므로 출력도 두 배로 늘어납니다. 아마도 두 번째 열의 내용에 대한 테스트를 추가하거나 다음과 같이 실행하여 주어진 ID를 가진 줄만 확인할 수 있습니다.

grep DC holiday_india.txt | bash holiday.sh

(물론 헤더 줄도 건너뜁니다. 또는 줄 시작 부분에서 월/년이 올바른지 확인할 수도 있습니다.)

이것은 ksh로 태그가 지정되었지만 bash를 사용했습니다. kshI have support 의 사본은 제가 사용한 유일한 새로운 구문이라고 생각합니다.${foo:N:L}

관련 정보