I am on ksh (Solris SunOS 5.10)
I have a variable $VAR and want to write an if which runs code only if the variable matches the format dd.mm.yyyy
e.g 01.01.2009, 05.12.1998, etc.
How can I do this?
if [[ "${VAR}" == [0-9][0-9]\.[0-9][0-9]\.[0-9][0-9][0-9][0-9] ]]; then
echo "Variable matches format dd.mm.yyyy"
fi
Related
How can I validate that my datetime string has a valid ISO-8601 format with timezone (+0200) through a bash script?
The acceptable format is only %Y-%m-%dT%H:%M:%S+0200.
EDIT: I'm fine with having the year as 0001, 9999 or any random permutation of 4 digits. I just need to enforce the syntactical check.
Here's a simple bash script which tests the given parameter against a regex for an extended (not basic/shortened) ISO-8601 format which, following the question, requires all the fields to be present:
#!/bin/bash
if [[ $1 =~ ^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}T?[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}([\.,][[:digit:]]+)?\+0200$ ]]
then
echo correct format
else
echo incorrect format
fi
Wikipedia's article on ISO-8601 says that the format allows the omission of the day field, but the above regex requires it, following the question's example. The regex allows the T to be optional, following the Wikipedia article. I've added optional support for fractional seconds (the ([\.,][[:digit:]]+)? portion), again based on the Wikipedia article.
The regex does not do any range checking of the values.
If you want your ISO date to be validated for any timezone, including the format
1970-01-01T00:00:00Z
1970-01-01T00:00:00+0200
Then you can use this regex:
[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|\+[0-9]{4})$
#!/bin/bash
if [[ $1 =~ [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|\+[0-9]{4})$ ]]
then
echo "ISO date";
else
echo "Malformed date";
fi
Keep in mind that [[ ]] is not POSIX compliant, this limits its portability.
Here is a solution that doesn't use any regex and uses date parsing of gnu-date:
s='2021-08-23T12:10:35+200'
[[ $s == *'+200' && $(TZ=CET date -d "$s" '+%FT%T' 2>/dev/null) == "${s%+*}" ]] &&
echo 'ok' || echo 'nope'
I have nested for loops going through dates and create a date. How can I check if that specific date is on the weekend or not?
String date is in the format of mm/dd/yyyy but can easily be changed. Each has its own variable $m $d $y
if [[ $(date +%u) -gt 5 ]] ; then
#do something
fi
above code works with current date, not sure how to translate that to accepting a string date.
You could use Ruby Date#cwday in your bash script. For example:
#!/bin/bash
y=2019
m=11
d=10
ruby -rtime -e "puts ([6,7].include? Date.new($y,$m,$d).cwday)"
which outputs true
I like more to use the variable directly:
if [[ $(date -d $your_variable +%u) -gt 5 ]]; then
#do something
fi
Just makes the code cleaner in my opinion.
This question already has answers here:
Validate date format in a shell script
(13 answers)
Closed 4 years ago.
I would like to ask if there is a way to validate if the variable passed is in this kind of sample format "06-10" or "10-01". It was really a challenge to me on how to start and echnically the "6-10" stands for "June 10" and "10-01" stands as "October 1", overall it needs to have like of a "Month-Day" valid in number format. I would like to have an if-then statement that would validate if the variables passed are in correct, something like these:
#!/bin/bash
# This script will ONLY accept two parameters in number format
# according to "MM-DD" which is "XX-XX"
# To run this script: ./script.sh xx-xx xx-xx
DATE1=$1
DATE2=$2
if [DATE1 is in correct format] && [DATE2 is in correct format]
then
echo "Correct format"
echo "DATE1 = $DATE1"
echo "DATE2 = $DATE2"
else
echo "Not correct format"
exit 1
fi
The if-statement would look like this:
if [[ $DATE1 =~ ^[0-9]{1,2}-[0-9]{1,2}$ ]] && [[ $DATE2 =~ ^[0-9]{1,2}-[0-9]{1,2}$ ]]
It checks if the date has the string format ##-##.
replacing the regex on the if statement worked by using this:
^(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$
I am making an adjustment a bash script of mine to output the ordinal part (st, nd, rd, th) of a day of month. I am trying to adjust it to be used within a date pattern in the date command.
Here is a simple test to determine if day of month from date command is an int:
dayOfMonth=$(date +"%d") && [[ ${dayOfMonth} =~ ^[0-9]+$ ]] && echo ${dayOfMonth} is an int || echo ${dayOfMonth} is NOT an int
Output is as I expect
01 is an int
Now I put that code into a script:
#!/bin/bash
[[ ${1} =~ ^[0-9]+$ ]] && echo ${1} is an int || echo ${1} is NOT an int
Seems OK:
dateTest.sh 12
12 is an int
But when I try to use it within a date command, the script is giving me conflicting output. echo sees 12 but the test is seeing %2
date --date='06/12/2012 07:21:22' +"`dateTest.sh %d`"
12 is NOT an int
To clarify my purpose, the end result of the script will be something like this:
#!/bin/bash
n=$(date +"%d")
if [ $# -ge 1 ] ; then
n=$1
if ! [[ $n =~ ^[0-9]+$ ]] ; then
echo Arg dateInteger [$dateInteger] must be an integer.
exit 1
fi
fi
if [ $n -ge 11 -a $n -le 13 ] ; then
echo "th"
else
case $(( $n%10 )) in
1)
echo st
;;
2)
echo nd
;;
3)
echo rd
;;
*)
echo th
;;
esac
fi
So that I can it like this:
date --date='06/12/2012 07:21:22' +"%A, %d`dateTest.sh %d` of %B %Y, %I:%M:%S %p"
which would output
Tuesday, 12th of June 2012, 07:21:22 AM
Finished script re-write. Thanks to input from #GordonDavisson, I completed my script re-write: http://pastebin.com/xZ1afqqC. Now it either outputs just the ordinal from an integer, or will output a fully formatted date where you can use standard format strings from date with the addition of "%O" for the ordinal.
You're doing things in the wrong order -- you have to turn "%d" into an integer (the day of the month) before passing it to your script, not after. Consider the command:
date --date='06/12/2012 07:21:22' +"`dateTest.sh %d`"
What this does is run dateTest.sh %d, i.e. it passes "%d" as the argument to your script. The script naturally outputs "%d is not an int". This is then used as the format string for the date command, i.e. date --date='06/12/2012 07:21:22' +"%d is not an int". The date command replaces the "%d" part with the day number, and leaves the rest alone, giving "12 is not an int".
In order to make this work, you have to get the day number first, then pass that to your script. Something like this:
dateTest.sh "$(date --date='06/12/2012 07:21:22' +"%d")"
Unfortunately, your end result script also wants a bunch of other date formatting done that can't be passed to the dateTest script. I think in that case it'd be best to do it in stages:
dayWithSuffix="$(dateTest.sh "$(date --date='06/12/2012 07:21:22' +"%d")")"
date --date='06/12/2012 07:21:22' +"%A, $dayWithSuffix of %B %Y, %I:%M:%S %p"
BTW, several general scripting suggestions:
Send error/debug output to stderr, not stdout, so it doesn't get confused with the script's regular output (part of the problem here). For example, echo "${1} is NOT an int" >&2
Speaking of which, put strings that contain variables in double-quotes (as I did in that last example) to avoid weird misparsing of whitespace, wildcards, etc. Your result script, for example, contains echo Arg dateInteger [$dateInteger] must be an integer. -- you probably don't realize that under certain circumstances the [$dateInteger] part will be replaced by a list of filenames.
Finally, use $( ... ) instead of backquotes. In most cases they're equivalent, but the parenthesis version is easier to read and avoids some weird parsing oddities of the contents. Notice how I nested two such expressions in the assignment to dayWithSuffix? That's much trickier to get right with backquotes.
I have a date field from a file with 50 dates in mm/dd/yy format. How can I convert it to yymmdd?
I have seen questions similar, but going the opposite direction. I cant seem to apply it the way I need it.
Dates are saved in file as 01/20/72 and I need to convert them to 720120
Currently I have $bDate +%y%m%d as the command, but it is wrong.
Thanks in advance!!
string manipulation: bash regular expressions suffice here:
date="04/13/06"
d='[[:digit:]]'
if [[ $date =~ ($d$d)/($d$d)/($d$d) ]]; then
newdate=${BASH_REMATCH[3]}${BASH_REMATCH[1]}${BASH_REMATCH[2]}
fi
echo $newdate
060413
If you're repeatedly doing this, make it a function:
mdy2ymd() {
local d='[[:digit:]]' newdate
if [[ $1 =~ ($d$d)/($d$d)/($d$d) ]]; then
newdate=${BASH_REMATCH[3]}${BASH_REMATCH[1]}${BASH_REMATCH[2]}
fi
echo $newdate
}
you can use sed and its internal regexp storing vars like
echo "01/20/72" | sed -r 's#(..)/(..)/(..)#\3\1\2#g'