최종 목표는 변수 YYYYMMDD를 설정하는 것입니다. 여기서 DD는 두 변수(01 또는 16) 중 하나입니다.
두 값 중 하나로 변수를 생성하려고 합니다.
이것이 내가 지금까지 가지고 있는 것이지만 작동하지 않습니다.
DYA=date +%d
DYB=IF [["$DYA" -ge 16]]; then 16
else 01
fi
YR=2020
MO=03
FD="$YR$MO$DY"
ECHO "$FD"
답변1
bash
버전 4.2 이상 사용 :
#!/bin/bash
printf -v day '%(%e)T' -1
if [[ $day -lt 16 ]]; then
# 1st half of the month
day=01
else
# 2nd half of the month
day=16
fi
printf '%(%Y%m)T%s\n' -1 "$day"
첫 번째는 printf
이번 달의 날짜를 10진수로 변수에 인쇄합니다 day
. 이러한 if
명령문은 해당 값으로 제한되거나 01
해당 16
값에 따라 제한됩니다.
마지막 것은 printf
현재 연도와 월을 인쇄한 다음 그 끝에 01
or 문자열을 추가합니다.16
-1
호출에 대한 인수는 printf
형식 %(...)T
문자열이 현재 시간을 형식화된 타임스탬프로 사용하도록 합니다( bash
4.3 이상을 사용하는 경우 첫 번째 호출에서는 암시적이므로 이를 엄격히 요구하지 않습니다).
더 컴팩트한 버전 bash
:
#!/bin/bash
printf -v day '%(%e)T' -1
printf '%(%Y%m)T%.2d\n' -1 "$(( (day < 16) ? 1 : 16 ))"
여기에서는 공개 함수를 사용하여 산술 확장 테스트를 수행합니다.삼항 연산자 ?:
. 16보다 작 1
으면 $day
결과는 문자열이고, 16
16보다 크면 결과는 문자열입니다. 그런 다음 산술 확장의 결과는 0으로 채워진 정수 형식으로 지정되고 현재 연도와 월 뒤에 삽입됩니다.
귀하의 코드와 관련하여 :
- 및
[[ ... ]]
양쪽에 공백이 필요하다는 점에 유의하세요(음, 명령 종결자이므로 공백 없이 즉시 나타날 수 있습니다).[[
]]
;
date
명령의 출력을 변수에 넣으 려면 명령 대체를 사용하십시오day=$( date +%e )
.if
이는 값을 출력하는 것이라면 귀하의 명령문에 해당됩니다(그러나 그렇지 않습니다).- Unix 명령은 대소문자를 구분하므로
ECHO
아마도echo
. - 시간 형식 출력 및
%d
. 산술 문맥(문장)에서 이러한 값을 사용하면 값이 다음과 같이 해석됩니다.01
31
if
01
07
8진수값을 입력하면08
합계 오류가 발생합니다09
(잘못된 8진수입니다). 그래서 나는%e
과 사이에 0이 아닌 패딩된 정수를 얻는 데 사용합니다.1
31
마지막 요점에 관해서 : 나는 또한 사용할 수 있습니다
printf -v day '%(%d)T' -1
01
와 사이에 0 패딩 값을 얻으려면 31
다음을 사용해야 합니다.
if [[ 10#$day -ge 16 ]]; then
쉘이 문자열을 8진 정수 대신 10진 정수로 해석하도록 강제합니다.
/bin/sh
스크립트 로 ( bash
4.2 이전 버전에서도 작동함(예: bash
macOS의 기본 셸):
#!/bin/sh
day=$( date +%e )
if [ "$day" -lt 16 ]; then
# 1st half of the month
day=01
else
# 2nd half of the month
day=16
fi
date +"%Y%m$day"
표준 쉘에는 형식 문자열이 sh
없으므로 날짜 문자열 형식을 사용해야 합니다 . 대신 테스트 에도 사용됩니다 (그리고 변수는 큰따옴표로 묶어야 합니다).%(...)T
bash
date
[ ... ]
[[ ... ]]
더 컴팩트한 버전 /bin/sh
:
#!/bin/sh
day=$( date +%e )
printf '%s%.2d\n' "$(date +%Y%m)" "$(( (day < 16) ? 1 : 16 ))"
이 보다 컴팩트한 버전은 컴팩트 bash
변형에서 파생되었습니다. 유일한 차이점은 date
현재 연도와 월의 형식을 지정하는 것입니다.
답변2
위의 내용을 달성하려면 다음 코드를 사용할 수 있습니다. #touch mycode.sh
#!/bin/bash
export DD=$(date +%d)
export YYYY=$(date | awk '{print $6}')
export MM=$(date +%m)
echo "$YYYY$MM$DD"
if [[ $DD -eq 16 || $DD -eq 01 ]];then
echo "$DD"
else
echo " The days are not 1st or 16th "
fi
#sh mycode.sh
출력/출력
20200303
답변3
위의 작업은 다음과 같습니다. 작업 코드는 다음과 같습니다.
export day=$(date +%d)
export YR=$(date | awk '{print $6}')
export MM=$(date +%m)
echo $DY
echo "$YR$MM$day"
if [[ $day -ge 16 ]]; then
day=16
else
day=01
fi
printf '%(%Y%m)T%s\n' -1 "$day"
export FD="$YR$MM$day"
echo $FD
답변4
dd=$(date +%d)
# values 08 and 09 will not work with arithmetic the way you expect
d=${dd#0} # remove any leading 0
if [ "$d" -ge 16 ] ;then
half=16
else
half=01
fi
date "+%Y%m$half"
이 코드가 가장 이해하기 쉽다고 생각합니다. 유일한 문제는 쉘 산술 표현식과 digital로 시작하는 숫자를 사용하는 것입니다 0
. 이는 이전에 접해 본 적이 없다면 아마 깨닫지 못할 것입니다. 형식 문자열은 맨페이지 date
에 설명되어 있습니다 . ( 또는 ) 구현 strftime(3)
에서는 변환 사양을 이해하지 못합니다 . 구성 은 (또는 다른 셸) 맨페이지의 "매개 변수 확장" 섹션 에 문서화되어 있습니다 .date
printf
%e
${dd#0}
bash(1)