"This Week" script: in bash, awk, or whatever.

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Message
Author
musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#61 Post by musher0 »

MochiMoppel wrote:
musher0 wrote:And MM, any reason why your syntax is different than mine for
< date '+%d' >? They give the same result.
Exactly which syntax are you referring to?
Hello MM.

In your "date-based" script, earlier, line 6, you have used the form
< date +%w >, without quotes, whereas I thought that single or double
quotes were needed around the date parameters, as in < date '+%w' >.

No big deal, BTW. TIA for any insight.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#62 Post by MochiMoppel »

Quotes are not needed as long as the parameter contains no spaces.
Much more important is to understand the difference between date +%d and date +%-d. All your scripts will fail if you don't fix this.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#63 Post by musher0 »

MochiMoppel wrote:Quotes are not needed as long as the parameter contains no spaces.
Much more important is to understand the difference between date +%d and date +%-d. All your scripts will fail if you don't fix this.
Please explain.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#64 Post by MochiMoppel »


musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#65 Post by musher0 »

Thanks.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
puppy_apprentice
Posts: 299
Joined: Tue 07 Feb 2012, 20:32

#66 Post by puppy_apprentice »

musher0 wrote:@MochiMoppei and puppy_apprentice:
I studied it, but I really do not understand the random color part in
puppy_apprentice's script.
Forgot for the while my earlier script where i extracted colors from 'cal | grep -wn --color=always "$(date +%-d)"' output and check again this, where colors are written stright in escape sequences:

Code: Select all

#!/bin/sh
colors=$(echo -e "34\n35\n36\n37"); colmatrix=($colors); r=$((RANDOM%4)); echo -e "\e[${colmatrix[$r]}m Hello World! \e[0m"
this is simpler version without bash arrays:

Code: Select all

echo -e "\e[1;3$((RANDOM%9))m Hello World! \e[0m"
this '$((RANDOM%9))' every time the script is ran will give numbers from 0 to 9 so bash will execute eg. this:

Code: Select all

echo -e "\e[1;35m Hello World! \e[0m"
musher0 wrote:Worse: I do not understand the need for it! :(
To make scripts more fancy ;)

Yesterday, i've changed my terminal prompt to this:

Code: Select all

PS1="\[\e[1;3$((RANDOM%9))m\][\w]>\[\e[0m\]"
You can ask why? It is not practical and worthless.

My answer is: Because i can and know how to do this! ;)
musher0 wrote:In particular, the part X1X2, etc. and the line of dates. How do you get
that XIX2, etc. part to appear? In an hex editor? I could not reproduce
it by any means I know.
No hex editor. All colors in console are ANSI escape sequences. Try this:

Code: Select all

cal | grep -wn --color=always "$(date +%-d)" >output.txt
If you look into output txt you will see escape sequences, where "ESC" you have to read as '\e' and from now you will know how to ectract colors using bash '${string:start:end}' ;)
musher0 wrote:Hello MM.

In your "date-based" script, earlier, line 6, you have used the form
< date +%w >, without quotes, whereas I thought that single or double
quotes were needed around the date parameters, as in < date '+%w' >.

No big deal, BTW. TIA for any insight.
MochiMoppel wrote:Quotes are not needed as long as the parameter contains no spaces.
Much more important is to understand the difference between date +%d and date +%-d. All your scripts will fail if you don't fix this.
There was misunderstanding between you both. Mochi was thinking about option 'w' in grep not in date command.

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#67 Post by rufwoof »

This is mine
Attachments
ps1.png
(41.91 KiB) Downloaded 269 times
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
trapster
Posts: 2117
Joined: Mon 28 Nov 2005, 23:14
Location: Maine, USA
Contact:

#68 Post by trapster »

Vertical verson :D

Code: Select all

# for days in {0..6}; do date "+%a %d" --date="$days day" ; done
Fri      23
Sat    24
Sun   25
Mon  26
Tue    27
Wed  28
Thu   29
#
trapster
Maine, USA

Asus eeepc 1005HA PU1X-BK
Frugal install: Slacko
Currently using full install: DebianDog

User avatar
puppy_apprentice
Posts: 299
Joined: Tue 07 Feb 2012, 20:32

#69 Post by puppy_apprentice »

rufwoof wrote:This is mine
Nice ;)

but my prompt changing colors every time (almost, it depends on seed of random i think) i start console ;)

I wanted do make this in one console session, but PS1 var is loaded only once ;(
Attachments
various-colors-prompt.jpg
(54.27 KiB) Downloaded 263 times

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#70 Post by musher0 »

Hello all.

Here is an article in the Linux Journal about calculating days.
It's tangent to the subject of this thread, I think.
The author uses some awk and some sed.

BFN.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#71 Post by musher0 »

@puppy_apprentice:

Regarding your first line in your 2nd cur-week script

Code: Select all

sn=$(echo -e "0\n15")
I think I'm beginning to understand:

Code: Select all

a=(echo blabla);echo ${a[*]}
echo blabla
But:

Code: Select all

a=(echo blabla);${a[*]}
blabla
I was not used to perceiving arrays this way. Your array can be
conceptualized in two ways: as data storage and as a command.

"Eureka" moment! :)

BFN.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
puppy_apprentice
Posts: 299
Joined: Tue 07 Feb 2012, 20:32

#72 Post by puppy_apprentice »

I've used them as data storage:

Code: Select all

# list of elements a:
a=$(echo -e "blabla\nmamba") #this is version for one liners scripts
#normally is:
#a="blabla
mamba"
#
# list a is assigned to array b:
b=($a)
echo ${b[0]} #prints first (index 0) element from array b - 'blabla'
echo ${b[1]} #prints second (index 1) element from array b - 'mamba'
but it could be written simpler like this:

Code: Select all

b=(blabla mamba)
echo ${b[0]}
echo ${b[1]}
Arrays are good you can sometimes use them instead of IF or CASE:

Code: Select all

#!/bin/sh
daysofweek=(Monday Tuesday Wendesday Thursday Friday Saturday Sunday) # $1 = 0 to 6
echo "You have choosen ${daysofweek[$1]}"

#it is simpler and shorter than this:
echo "You have choosen:"
case $1 in
  0) echo Monday ;;
  1) echo Tuesday ;;
  2) echo Wendesday ;;
  3) echo Thursday ;;
  4) echo Friday ;;
  5) echo Saturday ;;
  *) echo Sunday
esac

commands=($(echo ${RANDOM}) $(date +%d)) #$1 =  0 or 1
output=${commands[$1]}
echo $output

User avatar
puppy_apprentice
Posts: 299
Joined: Tue 07 Feb 2012, 20:32

#73 Post by puppy_apprentice »

musher0 wrote:Hello all.

Here is an article in the Linux Journal about calculating days.
It's tangent to the subject of this thread, I think.
The author uses some awk and some sed.

BFN.
I've written script for that without sed and awk:

Code: Select all

#!/bin/sh
#dow.sh

day=$1
month=$2
year=$3

# array with names of days
nod=($(cal $month $year | head -2 | tail -1))

# vertical list of days in week that include $day
cdl=$(cal $month $year | grep -w "$day" | grep -Eo "[0-9]*[0-9]*")

# number of days in week that include $day
nad=$(echo "$cdl" | grep -Ec "[0-9]*[0-9]*")

# number of days in week before $day
ndb=$(echo "$cdl" | grep -wB 7 "$day" | grep -Ec "[0-9]*[0-9]*")

# number of days in week after $day
nda=$(echo "$cdl" | grep -wA 7 "$day" | grep -Ec "[0-9]*[0-9]*")

if (( $nad == 7 ));
then
	echo "$day/$month/$year is ${nod[ndb-1]}"
fi

if (( $nad < 7 )) && (( $day < 7 ));
then
	echo "$day/$month/$year is ${nod[7-nda]}"
fi

if (( $nad < 7 )) && (( $day > 7 ));
then
	echo "$day/$month/$year is ${nod[ndb-1]}"
fi
Works for tests from article:

Code: Select all

DOW of 3 june 2011 = 6
DOW of 1 july 2011 = 6
DOW of 2 may 2011 = 2
DOW of 16 may 2011 = 2

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#74 Post by MochiMoppel »

musher0 wrote:Here is an article in the Linux Journal about calculating days.
:lol: What I liked best is his remark "The solution I'm going to work with is likely more complicated than necessary, but it's mine and I'm sticking with it."

Complicated indeed. He didn't explain why he uses cal. He *could* have done this with a single date command, but I guess that would have been too easy - and wouldn't fill the page in the Linux Journal.
puppy_apprentice wrote:I've written script for that without sed and awk:
Nice exercise!
Why do you stress that you didn't use sed or awk? A challenge? IMO grep is the least powerful tool for this kind of job, but as we see it can get the work done.

I've also written a script, using even less tools. Should produce the same result. No grep, no head, no tail, Just bash and cal. To increase the fun, no comments either :twisted:

Code: Select all

#!/bin/bash
day=3
month=6 
year=2011

CAL=$(cal $month $year)
CAL=${CAL#*$'\n'}
CAL=(${CAL//   / x })
while [[ ${CAL[$i]} != $day ]] ;do ((i++)); done
echo "$day/$month/$year is ${CAL[$((i%7))]}"

User avatar
puppy_apprentice
Posts: 299
Joined: Tue 07 Feb 2012, 20:32

#75 Post by puppy_apprentice »

MochiMoppel wrote: Nice exercise!
Why do you stress that you didn't use sed or awk? A challenge? IMO grep is the least powerful tool for this kind of job, but as we see it can get the work done.
It is mine and i'm sticking with it. :lol:

I've thought too that it can be written simpler. We have calendar so we don't need many calculations. We need only search trough it.

But yours is much simpler. Did i call you a Ceasar of Console Empire earlier? ;)

But my (algorithm) is easier to translate to other languages (on first view).

Your solution is nice (you used modulo, very nice function eg. in ciphers eg. ROT13):
[debugging mode on]

Code: Select all

#!/bin/bash
day=3
month=6
year=2011

CAL=$(cal $month $year)

echo "$CAL"

CAL=${CAL#*$'\n'}

echo ${CAL[*]}

CAL=(${CAL//   / x })

echo ${CAL[*]}

while [[ ${CAL[$i]} != $day ]] ;do ((i++)); done
echo "$day/$month/$year is ${CAL[$((i%7))]}" 
[debugging mode off]

There are some other solutions.

Some theory and history:
https://en.wikipedia.org/wiki/Perpetual_calendar

Programming algorithms, in Polish, but people familiar with programming languages should understand them:
https://pl.wikipedia.org/wiki/Kalendarz_wieczny
Last edited by puppy_apprentice on Sat 24 Nov 2018, 12:09, edited 1 time in total.

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#76 Post by musher0 »

Hello.

No, MM, I did not understand all you are doing in that script!

After much groping in the dark, using fuzzy logic :( :lol:

Code: Select all

cal 6 2011 | rev | awk 'NR ~ /2|3/ { print $2 }' | rev
Since we know that day=3 is at the beginning of the month, and that line
2 has the names, it is likely that the 3rd day of the month will be in line 3.

$(NF-1) is giving errors when the month is parsed straight,
(first line of dates does not have enough fields)
so we reverse the listing.
Then we fish out the needed fields and
reverse the result again so it's readable.

I would need a way to iterate through the first line and find the position
of $day. Then it would be less amateurish.

BFN.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

some1
Posts: 117
Joined: Thu 17 Jan 2013, 11:07

#77 Post by some1 »

Then it would be less amateurish.

You probably have an empty line in output -> NF NOT set.
Try

Code: Select all

 awk 'NF>0{print $(NF-1);}'

musher0
Posts: 14629
Joined: Mon 05 Jan 2009, 00:54
Location: Gatineau (Qc), Canada

#78 Post by musher0 »

Thanks, some1.

I'll keep that on the back burner for now, because I think I have found, in
the meantime, a "awk-less" variant to MM's puzzle, although not as elegant
as his. But it taught me how to juggle variables from array to string.

Code: Select all

date=3;A=(`cal 6 2011 | grep -vE [[:alpha:]] | rev`);for pos in {0..6};do [ "$date" = "${A[$pos]}" ] && POS=$pos;done;B=(`cal 6 2011 | grep -vE [[:digit:]] | rev`);day="`echo ${B[$POS]} | rev`";echo "$day $date"
Result:
fr 3
What do you think?

BFN.
musher0
~~~~~~~~~~
"You want it darker? We kill the flame." (L. Cohen)

User avatar
rufwoof
Posts: 3690
Joined: Mon 24 Feb 2014, 17:47

#79 Post by rufwoof »

Busybox date has a -D option

Code: Select all

busybox date -D "%d%m%Y" -d "03062011" +"%a"
... returns Fri
[size=75]( ͡° ͜ʖ ͡°) :wq[/size]
[url=http://murga-linux.com/puppy/viewtopic.php?p=1028256#1028256][size=75]Fatdog multi-session usb[/url][/size]
[size=75][url=https://hashbang.sh]echo url|sed -e 's/^/(c/' -e 's/$/ hashbang.sh)/'|sh[/url][/size]

User avatar
MochiMoppel
Posts: 2084
Joined: Wed 26 Jan 2011, 09:06
Location: Japan

#80 Post by MochiMoppel »

rufwoof wrote:Busybox date has a -D option
Sure but GNU date has not and you don't need this option here anyway.

Code: Select all

#!/bin/bash
day=3 
month=6
year=2011 
date -d "$year-$month-$day" +"$day/$month/$year is %a"

Post Reply