현재 날짜에서 "xyz/[int][int]/[int][int][int][int]" 형식의 날짜를 빼는 방법은 무엇입니까?

현재 날짜에서 "xyz/[int][int]/[int][int][int][int]" 형식의 날짜를 빼는 방법은 무엇입니까?

상상하다

내 컨테이너의 마지막 배포 날짜는 다음 형식입니다.

월/일/년 또는 2024년 2월 11일.

마지막 배포 날짜를 출력하는 방식을 변경할 수 없습니다.

현재 날짜에서 마지막 배포 날짜를 뺀 다음 마지막 배포 날짜가 2개월 이상 지난 경우 파일에 쓰고 싶습니다.

예컨테이너1-마지막-deploy.txt:

last deployed: jan/01/2024

이런 파일이 여러 개 있습니다.

문제는 달이 문자로 제공된다는 것입니다. 정규식을 사용하여 날짜를 얻을 수 있습니다.

내가 생각한 한 가지 해결책은 다음과 같이 달을 사전에 넣는 것입니다.

dict=(
  ['jan']=1
  ['feb']=2
)

하지만 더 좋은 방법이 있을 겁니다.

알파벳 월을 정수로 변환할 수 있나요?

이는 macOS의 bash용이며 bash 3 솔루션이 바람직합니다.

답변1

MacOS date- 날짜 문자열을 에포크 이후 초로 변환

date이 명령은 libc 함수를 통해 문자열 형식의 월을 이해할 수 있습니다 strptime(3). 나는 macos가 없어서 답변을 테스트할 수 없지만 macos에 따르면date 남성페이지:

date [-jRu] -f input_fmt new_date [+output_fmt]

[...]

   -f      Use input_fmt as the format string to parse the new_date provided rather than using the
           default [[[mm]dd]HH]MM[[cc]yy][.ss] format.  Parsing is done using strptime(3).

이제 매뉴얼 페이지에서 입력 날짜의 형식을 지정하는 방법만 알면 됩니다.strptime(3):

       %b or %B or %h
              The month name according to the current locale,  in  abbreviated
              form or the full name.

       %d or %e
              The day of month (1-31).

       %Y     The year, including century (for example, 1991).

따라서 이에 따르면 입력 형식은 다음과 같아야 합니다 "%b/%e/%Y".

다음으로 다음 플래그를 사용해야 합니다 date.

   -j      Do not try to set the date.  This allows you to use the -f flag in addition to the + option
           to convert one date format to another.  Note that any date or time components unspecified
           by the -f format string take their values from the current time.

마지막으로 결과에서 현재 시간을 뺄 수 있기를 원하므로 +출력_fmt할 것이다:

       %s     The number of seconds since the Epoch, 1970-01-01 00:00:00
              +0000 (UTC).  Leap seconds are not counted unless leap
              second support is available.

따라서 날짜 형식을 epoch로 변환하는 결과 명령은 다음과 같아야 합니다.

$ DATE="jan/01/2024"
$ date -jf "%b/%e/%Y" $DATE +%s
1704060000

다시 말하지만, Macos가 없기 때문에 이를 확인하기 위해 테스트할 수 없습니다. 또한 소문자 월을 허용할지 확실하지 않지만 월을 대문자로 바꿔야 하는 경우 다음 $DATE으로 바꿀 수 있습니다.${DATE^}

완전성을 기하기 위해 다음 명령을 사용하여 동일한 작업을 수행하는 방법도 보여 드리겠습니다.

GNU date- 날짜 문자열을 에포크 이후 초로 변환

dateGNU 버전은 더 많은 자유를 제공하기 때문에 더 쉽습니다.

그것에서남성페이지:

       The --date=STRING is a mostly free format human readable date
       string such as "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29
       16:21:42" or even "next Thursday".  A date string may contain
       items indicating calendar date, time of day, time zone, day of
       week, relative time, relative date, and numbers.  An empty string
       indicates the beginning of the day.  The date string format is
       more complex than is easily documented here but is fully
       described in the info documentation.

date따라서 내 컴퓨터에서 테스트한 결과 명령이 이해할 수 있도록 입력에서 슬래시를 제거해야 합니다 .

$ DATE="jan/01/2024"
$ echo ${DATE//\// }
jan 01 2024
$ date --date "${DATE//\// }"  +%s
1704060000

현재 날짜에서 빼기

이제 원래 날짜의 신기원 시간을 갖게 되었습니다. 그냥 변수에 저장하면 됩니다. 예를 들어 MacOS에서는 다음과 같습니다.

$ ORIG_DATE=$(date -jf "%b/%e/%Y" $DATE +%s)

에포크 이후 현재 날짜를 초 단위로 보려면 다음을 수행하세요.

$ date +%s
1704965965

이제 차이를 초 단위로 계산하는 방법은 간단합니다.

$ echo $(( $(date +%s ) - $ORIG_DATE ))
905967

답변2

정확한 요구 사항을 얻으려고 노력해야 합니다(어쩌면 요구 사항이 있지만 여기에 명시하지 않았을 수도 있음).

  • 하나는 월 약어로 가정되는 로케일입니다. 예를 들어, 독일어 로케일에서 월 이름은 영어 전용 애플리케이션에서 인쇄된 날짜를 구문 분석할 때 문제를 일으킬 수 있습니다(예: mayis maioctis in German okt).

    사용된 월 이름이 현재 로캘과 일치하면 date -d "$(echo jan/01/2024 | tr / ' ')"배포 날짜를 간단히 구문 분석할 수 있습니다 .

  • 또 다른 질문은 날짜 차이를 계산하는 방법입니다.

    • 일수(약 60일)를 계산하려면 +%sformat 매개변수를 사용하여 배포 날짜와 현재 날짜를 초로 변환하고 해당 숫자를 뺀 후 결과가 60*86400보다 큰지 확인하면 됩니다.

    • 좀 더 복잡한 규칙(예: 월별 날짜 비교)을 따르고 싶다면 여전히 bash에서 수행할 수 있지만 더 어려워질 것입니다.

답변3

any date및 any를 사용하면 awk설명하는 대로 수행됩니다.

$ awk -v now="$(date +%m/%Y)" -v dif=2 -F'[ /]' '
    BEGIN {
        split(now,n)
        now = n[1] + (n[2] * 12)
    }
    {
        mth = ( index("janfebmaraprmayjunjulaugsepoctnovdec",$3) + 2 ) / 3
        cur = mth + ($5 * 12)
    }
    (now - cur) > dif
' file
last deployed: oct/01/2023

위의 코드는 이 입력 파일에서 실행됩니다.

$ cat file
last deployed: oct/01/2023
last deployed: nov/01/2023
last deployed: dec/01/2023
last deployed: jan/01/2024

입력의 월 이름이 Jan또는 와 같이 모두 소문자가 아닌 경우 JAN스크립트에서 $3으로 변경하면 됩니다.tolower($3)

답변4

사용행복하다(이전 Perl_6)

먼저 날짜를 유효한 날짜로 변환하십시오.ISO 8601날짜:

~$ raku -pe 'BEGIN my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12;  \
             s{ ^ .+? <( ( <.alpha>**3 ) (\/)  (\d**1..2)  (\/) (\d**4) } = "$4-{sprintf q[%02d], %months{$0.tclc}}-$2".Date;'  file
last deployed: 2024-01-01

걱정하지 마세요. 언제든지 다시 포맷할 수 있습니다.

~$ raku -pe 'BEGIN my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12;  \
             s{ ^ .+? <( ( <.alpha>**3 ) (\/)  (\d**1..2)  (\/) (\d**4) } = "$4-{sprintf q[%02d], %months{$0.tclc}}-$2".Date.mm-dd-yyyy("/");'  file
last deployed: 01/01/2024

이 라쿠 요소는 이제 라쿠이기 때문에날짜개체에 대해 수학적 계산을 수행할 수 있습니다.

~$ raku -pe 'BEGIN my %months = [Z=>] <Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec>, 1..12;  \
             s{ ^ .+? <( ( <.alpha>**3 ) (\/)  (\d**1..2)  (\/) (\d**4) } = Date.new(now) - "$4-{sprintf q[%02d], %months{$0.tclc}}-$2".Date ~ " days ago";'  file
last deployed: 46 days ago  

더 많은 코드 예제를 보려면 아래 링크를 참조하세요.

https://docs.raku.org/언어/temporal.html
https://github.com/Raku/examples/tree/master/categories/cookbook/03dates-and-times
https://raku.org

관련 정보