You are not logged in.

#1 2022-05-18 09:20:13

OlaffTheGreat
Member
Registered: 2013-06-03
Posts: 107

[Solved] bashcript issues using strftime

Hi folk,

I wrote the following script in order to provide temp text files containing formatted dates (ready to be copied when writing papers),
along with a current month working folder linked to /tmp/papers for quick access (plus empty template pdf files with the corresponding date in the title's stem).

#!/bin/sh
 
toyear=$(date +"%Y")
todaymonth=$(date +"%Y%m")
#yesterdaymonth=$(yesterday date +"%Y%m")
todayday=$(date +"%d")
todaydayy=$(date +"%e")
yesterday=$(date -d "yesterday" +'%d')
yesterdayy=$(date -d "yesterday" +'%e')
tomonthen=$(LC_ALL=en_US.UTF-8 date +"%B")
#yesterdaytomonthen=$(LC_ALL=en_US.UTF-8 yesterday date +"%B")
#... (other localizations) eg:
#tomonthde=$(LC_ALL=de_DE.UTF-8 date +"%B")
#tomonthcn=$(LC_ALL=zh_CN.UTF-8 date +"%B")

val1=$(date +%Y%m%d --date="yesterday")

mkdir /tmp/papers
ln -s $OFFICE/WorkFolder/$todaymonth /tmp/papers/.
touch /tmp/papers/$todaymonth$todayday\ -\ TodayPaper\ -\ .pdf
touch /tmp/papers/$todaymonth$yesterday\ -\ TodayPaper\ -\ .pdf

echo "– Published $todayday $tomonthen $toyear" > /tmp/papers/.timeden.txt
echo "– Published $yesterdayy $tomonthen $toyear" > /tmp/papers/.timeyen.txt
#(same lines with other localization)
xed /tmp/papers/.timeden.txt /tmp/papers/.timeyen.txt
#... (other localizations)

Some issues to address:
- I can't get "st/nd/rd" for "1st/2nd/3rd" and such (no option in strftime?).
- On the 1st of the month, I get a line with 30/31 of the same month instead of the yesterday's (preceding) month
  (my yesterdaymonth variable does not work, or I get last month always, even on following days).
- For the one digit dates (%e) (from the 1st to the 9th of the month),
  the echo command gives the intended gap for the 0, but without suppressing it
  (ie: I get  " – Published May  1st, 2022"
   instead of " - Published May 1st, 2022"
   notice the overnumerous space before 1st).

Any tip would is welcome.

Last edited by OlaffTheGreat (2023-04-12 07:58:24)


Lenovo Thinkpad x230 i5-3320M 2.6GHz 250GB SSD (M4) 16GB
SSD | SeaBIOS | GPT | BTRFS | OpenRC | Xfce4 | Zsh | Tmux | Spacemacs
* "Aware Newbie" *
Ibus IM for language script support (e.g. 日本語 - 中文)

Offline

#2 2022-05-20 07:20:37

seth
Member
Registered: 2012-09-03
Posts: 49,979

Re: [Solved] bashcript issues using strftime

- I can't get "st/nd/rd" for "1st/2nd/3rd" and such (no option in strftime?).

None that I'm aware of and it's also a very peculiar crank, https://en.wikipedia.org/wiki/Ordinal_indicator
You'll have to implement that yourself

Try

date +'%Y %B  %e' | read YEAR MONTH DAY

to limit the "date" invocation and also do away w/ pointless whitespace.

On the 1st of the month, I get a line with 30/31 of the same month instead of the yesterday's (preceding) month

To no surprise given the present script.

#yesterdaymonth=$(yesterday date +"%Y%m")

What is "yesterday"?? plan9 binary?

Offline

#3 2022-05-22 12:20:17

OlaffTheGreat
Member
Registered: 2013-06-03
Posts: 107

Re: [Solved] bashcript issues using strftime

Hi, thank you for your reply.

Ordinals are indeed a tad teedious. Implement it myself will not be within my habilities, so I'll keep changing them manually.

I added a variable valb=$(date +'%Y %B  %e' | read YEAR MONTH DAY) (I noticed the extra space before %e) and fiddle with it. I'll come back with more results.

About that "yesterday", it is only the remnant of experiments from the non-programmer fellow that I am, so, no Plan9 here.


Lenovo Thinkpad x230 i5-3320M 2.6GHz 250GB SSD (M4) 16GB
SSD | SeaBIOS | GPT | BTRFS | OpenRC | Xfce4 | Zsh | Tmux | Spacemacs
* "Aware Newbie" *
Ibus IM for language script support (e.g. 日本語 - 中文)

Offline

#4 2022-05-22 13:44:19

seth
Member
Registered: 2012-09-03
Posts: 49,979

Re: [Solved] bashcript issues using strftime

date +'%Y %B %e' | read YEAR MONTH DAY

will read the date into the variables $YEAR, $MONTH and $DAY
The stray blank was just for demonstration (cause we've the 21st)

English ordinals are fairly simply to do

case $DAY in
1)
DAY=1st
;;
2)
DAY=2nd
;;
3)
DAY=3rd
*)
DAY=${DAY}st
;;
esac

There's just no locale for that (and the concept doesn't exist in most locales)

"yesterday", it is only the remnant of experiments

You should get proper variables for yesterday by using "date -d yesterday"

Offline

#5 2022-05-22 15:25:09

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,442
Website

Re: [Solved] bashcript issues using strftime

What's the end goal of all of this?  I suspect this could be *much* cleaner and simpler.  Also by simplifying you'll avoid errors that you wont have to work around later.  I doubt you really want the second pdf 'touched' to have a name with today's year and month and yesterday's day number.  On January 1 2023 that would give a the "yesterday" pdf a value of January 31 2023 rather than December 31 2022 which is almost certainly what you'd really want - your approach would give the wrong value for yesterday's pdf on the first day of every month.

Last edited by Trilby (2022-05-22 15:32:13)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#6 2022-06-01 17:57:27

OlaffTheGreat
Member
Registered: 2013-06-03
Posts: 107

Re: [Solved] bashcript issues using strftime

The goal is to have template files with pre-formatted title and date ready to use (everyday) for writing papers (with different locales).
Obviously, it can be *much* simpler, that's an easy one. Programmer beginner here.

So, I tried the following code, which lead to a pdf file titled " - TodayPaper - .pdf", and two txt files containing both "– Published ",
plus a link to the parent folder "WorkFolder" instead of the intended current month:

#!/bin/sh

val=$(date +'%Y %B %e' | read YEAR MONTH DAY)

mkdir /tmp/papers
ln -s $OFFICE/WorkFolder/$MONTH /tmpr/papers/.

touch /tmpr/papers/$val\ -\ TodayPaper\ -\ .pdf
echo "_ Published $val" > /tmpr/.timeden.txt

This is a work in progress.
I'll focus on 1st on the month yesterdays, ordinals and locales when I'll get this right first.
For the workload, I use the falty script as it is.

I may require some time to figure all that out, but I'll get it.

Last edited by OlaffTheGreat (2022-06-01 17:58:53)


Lenovo Thinkpad x230 i5-3320M 2.6GHz 250GB SSD (M4) 16GB
SSD | SeaBIOS | GPT | BTRFS | OpenRC | Xfce4 | Zsh | Tmux | Spacemacs
* "Aware Newbie" *
Ibus IM for language script support (e.g. 日本語 - 中文)

Offline

#7 2022-06-01 18:48:21

seth
Member
Registered: 2012-09-03
Posts: 49,979

Re: [Solved] bashcript issues using strftime

Again

val=$(date +'%Y %B %e' | read YEAR MONTH DAY)

is nonsense. Try

date +'%Y %B %e' | read YEAR MONTH DAY
echo $YEAR
echo $MONTH
echo $DAY

What did you hope to fin in $val?

Offline

#8 2022-06-01 19:28:51

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,442
Website

Re: [Solved] bashcript issues using strftime

Seth, that will not work as the "read" runs in a different subshell due to the pipe.  All in all, I'd avoid all the variables and calculations, and just call date when the filenames / paths are needed, e.g.

mkdir -p /tmp/papers
ln -s $OFFICE/WorkFolder/$(date +%B) /tmp/papers/.

touch /tmp/papers/$(date "+%Y %B %e) - TodayPaper - .pdf
echo "_ Published $(date "+%Y %B %e")" > /tmpr/.timeden.txt
touch /tmp/papers/$(date -d yesterday "+%Y %B %e) - TodayPaper - .pdf

But this still doesn't make any sense.  I'm curious about your end goal, not the steps that you currently are planning to take to acheive the end goal ... because frankly, these steps don't make any sense and are highly error-prone.

Perhaps there could be a script that at the start would define a couple date format strings that could then be used throughout the script for different locales and different days - but this would be written quite a bit differently that what we're currently talking about.  Most likely this would involve a loop through all the locales.  Using a template and a loop would mean there would only be one (or maybe two) actual "touch" commands rather than many - if there are many, any change needs to be made in many places (thus error prone).


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#9 2022-06-01 19:42:24

seth
Member
Registered: 2012-09-03
Posts: 49,979

Re: [Solved] bashcript issues using strftime

Ah, bash inferiority…

read YEAR MONTH DAY < <(date +'%Y %B %e')

Offline

#10 2023-04-12 07:57:10

OlaffTheGreat
Member
Registered: 2013-06-03
Posts: 107

Re: [Solved] bashcript issues using strftime

A working version:

#!/bin/bash
#set -xe
#

day=$(date '+%d')
yday=$(date -d 'yesterday' '+%d')
jr=$(date '+%d')
yjr=$(date -d 'yesterday' '+%d')
temps="fr_FR.UTF-8"
ytemps="fr_FR.UTF-8"
time="en_US.UTF-8"
ytime="en_US.UTF-8"
ordinaux=("er" "")
yordinaux=("er" "")
ordinals=("st" "nd" "rd" "th")
yordinals=("st" "nd" "rd" "th")


if [[ "$temps" = "fr_FR.UTF-8" ]]; then
  case "$jr" in
    01) ordx="${ordinaux[0]}" ;;
     *) ordx="${ordinaux[1]}" ;;
  esac
fi

if [[ "$ytemps" = "fr_FR.UTF-8" ]]; then
  case "$yjr" in
    01) yordx="${yordinaux[0]}" ;;
     *) yordx="${yordinaux[1]}" ;;
  esac
fi

if [[ "$time" = "en_US.UTF-8" ]]; then
  case "$day" in
    01 | 21 | 31) ords="${ordinals[0]}";;
    02 | 22)      ords="${ordinals[1]}";;
    03 | 23)      ords="${ordinals[2]}";;
    *)            ords="${ordinals[3]}";;
  esac 
fi

if [[ "$ytime" = "en_US.UTF-8" ]]; then
  case "$yday" in
    01 | 21 | 31) yords="${yordinals[0]}";;
    02 | 22)      yords="${yordinals[1]}";;
    03 | 23)      yords="${yordinals[2]}";;
    *)            yords="${yordinals[3]}";;
  esac 
fi

#else
#  echo "Error: Unsuported LC_LOCALE."
#  echo "The value of LC_LOCALE did not match any of the comparison executed in if/elif."
#  echo "Please set a supported locale that will match."
#  exit 1

#fi


#fr_FR
echo "Publié le $(LC_TIME=fr_FR.UTF-4 date '+%-e')$ordx $(LC_TIME=fr_FR.UTF-8 date '+%B %Y')" 
echo "Publié le $(LC_TIME=fr_FR.UTF-8 date -d 'yesterday' '+%-e')$yordx $(LC_TIME=fr_FR.UTF-8 date -d 'yesterday' '+%B %Y')" 

#en_US
echo "Published on $(LC_TIME=en_US.UTF-8 date '+%B %-e')$ords, $(date '+%Y')"
echo "Published on $(LC_TIME=en_US.UTF-8 date -d 'yesterday' '+%B %-e')$yords, $(date '+%Y')" 

#zh_CN
echo "$(LC_TIME=zh_CN.UTF-8 date '+%Y年%_-m月%-e日')发布" 
echo "$(LC_TIME=zh_CN.UTF-8 date -d 'yesterday' '+%Y年%_-m月%-e日发布')"

It's a bit much, but it works.

A much simpler code (suggested to me):

#!/usr/bin/env bash
set -e
# given by parona on https://matrix.to/#/#gentoo:matrix.org

source <(locale)

function english_ordinal() {
    case $((${1} % 10)) in
        1) echo "st" ;;
        2) echo "nd" ;;
        3) echo "rd" ;;
        *) echo "th" ;;
    esac
}

function french_ordinal() {
    case $1 in
        1) echo "er" ;;
    esac
}

today="$(date '+%-d')"
yesterday="$(date -d yesterday '+%-d')"

case ${LC_TIME} in
    fr_FR*)
        echo "Publié le $(date '+%-e')$(french_ordinal ${today}) $(date '+%B %Y')"
        echo "Publié le $(date -d 'yesterday' '+%-e')$(french_ordinal ${yesterday}) $(date -d 'yesterday' '+%B %Y')"
        ;;
    en_*)
        echo "Published on $(date '+%B %-e')$(english_ordinal ${today}), $(date '+%Y')"
        echo "Published on $(date -d 'yesterday' '+%B %-e')$(english_ordinal ${yesterday}), $(date '+%Y')"
        ;;
    zh_CN*)
        echo "$(date '+%Y年%_-m月%-e日')发布"
        echo "$(date -d 'yesterday' '+%Y年%_-m月%-e日发布')"
        ;;
    *)
        echo "Error: Unsuported LC_TIME."
        echo "The value of LC_TIME did not match any of the comparison executed in case."
        echo "Please set a supported locale that will match."
        exit 1
        ;;
esac

Another suggestion points out the lack of exception in the latter for 11th, 12th and 13th:

if [[ "$LC_ALL" = "en_US.UTF-8" ]]; then
case ${1} in
  11|12|13)
    ord="${1}th" exit ;;
esac
case ${1:0-1} in
  1) ord="${1}st" exit ;;
  2) ord="${1}nd" exit ;;
  3) ord="${1}rd" exit ;;
  *) ord="${1}th" exit ;;
esac
elif [[ "$LC_ALL" = "fr_FR.UTF-8" ]]; then
case ${1} in
    1) ord="${1}er" exit;;
    *) ord="${1}" exit;;
esac
fi

Thread [solved], although open to suggestions.

Last edited by OlaffTheGreat (2023-04-12 08:01:49)


Lenovo Thinkpad x230 i5-3320M 2.6GHz 250GB SSD (M4) 16GB
SSD | SeaBIOS | GPT | BTRFS | OpenRC | Xfce4 | Zsh | Tmux | Spacemacs
* "Aware Newbie" *
Ibus IM for language script support (e.g. 日本語 - 中文)

Offline

Board footer

Powered by FluxBB