이 휴일 목록을 날짜 형식으로 변환하려면 스크립트가 필요합니다. 내 입력 파일
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을 얻은 다음 concat 연산자를 사용하여 날짜를 만듭니다.
아래는 내 스크립트입니다. 그러나 내가 직면하고 있는 문제는 어떤 열 아래에도 Y가 없으면 내 var를 공백으로 제공하고 공백이 실제 상태에도 나타난다는 것입니다.
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에 아무것도 없을 때 If 조건이 true로 나타나지 않도록 어떻게 해야 하는지 알려주세요.
이 스크립트의 O/P는 Y가 아닌 각 행의 21-52의 모든 열을 날짜로 변환하는 것입니다.
이제 그 점을 분명히 밝혔기를 바랍니다.
답변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}"
엘위치에서질소. 그러나 인덱스가 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를 사용하고 있습니다. ksh
나는 지원 사본을 가지고 있는데 이것이 내가 사용하고 있는 유일한 새로운 구문이라고 생각합니다.${foo:N:L}