How to evaluate date from a string - bash

Here are my files :
conf.txt
case1:fooYYYYmmdd.bar
case2:helloYYYYmmdd.world
script.sh
fname=`grep $1 conf.txt | cut -d ':' -f2`
When calling my script.sh with a parameter being case1 or case2, I obviously get my var fname fed with fooYYYYmmdd.bar or helloYYYmmdd.world.
How could I evaluate the date from my conf.txt so fname would be set with foo20181120.bar and hello20181120.world without going through breaking and building back my string ?

You could just declare a Date variable and use it in fname, like this:
Date=$(date +%Y%m%d)
fname=$(grep $1 conf.txt |sed "s/YYYYmmdd/$Date/g"|cut -d ':' -f2)
echo $fname

Related

Shell Date conversion and assign to Variable

I have requirement like convert a string date to below format and assign to variable for futher processing.
Input is string as below
str = 20210709
Need to get yesterday date and change the format to %Y-%m-%d
(date -d 'str -1 days' +'%Y-%m-%d')
and i am expecting output in a variable like below
dt = 2021-06-09
I tried like below
dt = date -d '20210709 -1 days' +'%Y-%m-%d'
and the error as below
-bash: d: command not found
Any ideas/Suggestions would be greatly appreciated.
You're missing a couple of things:
3.5.4 Command Substitution syntax
no spaces allowed around the = for variable assignment
str=20210709
dt=$(date -d "$str - 1 day" '+%F')
echo "$dt"
2021-07-08
dt=$(paste -d "-" <(echo $str |cut -c1-4) <(echo $str |cut -c5-6) <(echo $str |cut -c7-8))
If your version of linux doesn't like that syntax, then
dt=$(sed 's/\(....\)\(..\)\(..\)/\1-\2-\3/' <<< $str)

split date and time collide with space between them in bash

from my wp cli I receive a date format like this :
YYYY-mm-ddHH-mm-ss for example : 2020-02-2514:24:25
I would like to convert it to timestamp but the format date is incorrect.
I would like to split the date and time with space between them but I have no idea to do that currently.
with regex may be but I just seen how to replace space and I am a nooby with bash regex.
thank you for your help
Just use cut
root#a036fb1c94fa:~# DATE=$(echo "2020-02-2514:24:25" | cut -b-10)
root#a036fb1c94fa:~# TIME=$(echo "2020-02-2514:24:25" | cut -b11-)
root#a036fb1c94fa:~# TIMESTAMP=$(date -d "$DATE $TIME" +"%s")
root#a036fb1c94fa:~# echo $TIME
14:24:25
root#a036fb1c94fa:~# echo $DATE
2020-02-25
root#a036fb1c94fa:~# echo $TIMESTAMP
1582637065
Explanation:
echo "2020-02-2514:24:25" | cut -b-10
echo the string and cut it before the 10th byte
echo "2020-02-2514:24:25" | cut -b11-
echo the string and cut it from the 11th byte until the end
echo date -d "$DATE $TIME" +"%s"
give the right format to unix date command, with +"%s" to get its timestamp
You don't need any regex. You can select substrings in bash.
If the variable wpdate contains the string returned by wp cli, the corresponding timestamp can be put into the variable timestamp as follows:
timestamp=$(date '+%s' --date "${wpdate:0:10} ${wpdate:10:8}")
Explanation: ${wpdate:10:8} means the substring of wpdate starting at position 10 and containing 8 chars.

Get Year, Month, and Date from Variable

I have a variable of the format $var_YYYY_MM_DD_HH_MM_SS.txt
Eg: variable=sample_data_2017_01_01_10_22_10.txt
I need to extract the following from this variable:
Year=YYYY
Month=MM
Date=DD
Can you please help?
Use the native bash, regex operator ~ and use the captured groups to store them in variables for using it later.
variable="sample_data_2017_01_01_10_22_10.txt"
if [[ $variable =~ ^sample_data_([[:digit:]]{4})_([[:digit:]]{2})_([[:digit:]]{2}).*$ ]]; then
year="${BASH_REMATCH[1]}"
month="${BASH_REMATCH[2]}"
date="${BASH_REMATCH[3]}"
fi
You could try:
Year=$(echo $variable | cut -d '_' -f3)
Month=$(echo $variable | cut -d '_' -f4)
Date=$(echo $variable | cut -d '_' -f5)
This only works if you are sure your variable is laid out in the exact way you describe in your question though. It splits up the string delimited by the '_' character and then returns the field denoted -f argument to cut.
You can simply use read command with setting IFS='_'.
$ variable=sample_data_2017_01_01_10_22_10.txt
$ IFS='_' read -r tmp tmp Year Month Date tmp <<< "$variable"
$ echo "$Year : $Month : $Date"
2017 : 01 : 01
Using awk
Year=$(echo $variable | awk '{split($0,a,"_"); print a[3]}')
Month=$(echo $variable | awk '{split($0,a,"_"); print a[4]}')
Day=$(echo $variable | awk '{split($0,a,"_"); print a[5]}')
Building on some of the other awk solutions a more complete solution would be:
echo $variable | awk -F_ '{ printf "Year="$3"\nMonth="$4"\nDate="$5"\n" }'

bash script prints "No such file or directory" when comparing filenames to string

I am checking to see if a file I am hoping to create conflicts with a file that has the same name.
FILEPATH=/root/logs/pData*.csv
COMPPATH=/root/logs/pData*.csv.gz
shopt -s nullglob
thisYear="$(date +"%Y")"
thisMonth="$(date +"%m")"
thisDay="$(date +"%d")"
thisTime="$(date | cut -d ' ' -f 4 | tr : _)"
for file in $FILEPATH
do
fileYear="$(stat -c %y $file | cut -d'-' -f 1)"
fileMonth="$(stat -c %y $file | cut -d'-' -f 2)"
fileDay="$(stat -c %y $file | cut -d'-' -f 3 | cut -d' ' -f 1)"
fileTime="$(stat -c %y $file | cut -d ' ' -f 2 | cut -d '.' -f 1 | tr : _)"
if (("$fileYear" < '1990'))
then
fName="pData_"$thisYear"_"$thisMonth"_"$thisDay"_"$thisTime".csv.gz"
else
fName="pData_"$fileYear"_"$fileMonth"_"$fileDay"_"$fileTime".csv.gz"
fi
echo $fName
for file in $COMPPATH
do
if ('/root/logs/'$fName == $file)
then
echo "OOPS"
fi
done
done
The script works as intended for the most part, printing OOPS when I run into a file of the same name, but for files that don't exist it prints
./compress.sh: line 31: /root/logs/pData_2015_09_18_22_25_44.csv.gz: No such file or directory
Why is this printed?
How do I prevent this from happening?
The string comparison is wrong. Using single parentheses is creating a sub-shell and trying to execute '/root/logs/'$fName
Set your string compare to be:
if [[ '/root/logs/'$fName = $file ]]
See: http://www.tldp.org/LDP/abs/html/comparison-ops.html

How Do I Parse a Date in Shell?

Right Now I am trying to parse the values from my get time and date and break it down by each number
Format of the date/time
#!/bin/bash
prevDateTime=$(date +'%Y-%m-%d-%H:%M:%S')
echo "${prevDateTime}"
I want to be able to list it out like so
echo "${prevYear}"
echo "${prevMonth}"
echo "${prevDay}"
echo "${prevHour}"
echo "${prevMinute}"
echo "${prevSecond}"
and then like
echo "${prevDate}"
echo "${precTime}"
But I am not sure how to parse out the information any help would be great
A regular expression is probably the simplest solution, given the format of prevDateTime.
[[ $prevDateTime =~ (.*)-(.*)-(.*)-(.*):(.*):(.*) ]]
prevYear=${BASH_REMATCH[1]}
prevMonth=${BASH_REMATCH[2]}
# etc.
Technically, there's a "one"-liner to do this using declare:
declare $(date +'prevDateTime=%Y-%m-%d:%H:%M:%S
prevYear=%Y
prevMonth=%m
prevDat=%d
prevHour=%H
prevMinute=%M
prevSecond=%S')
It uses date to output a block of parameter assignments which declare instantiates. (Note that the command substitution is not quoted, so that each assignment is seen as a separate argument to declare. If there was any whitespace in the values to assign, you would have to switch to using eval with slightly different output from date.)
You can use read command with IFS to break down date components:
prevDateTime=$(date +'%Y-%m-%d-%H:%M:%S')
IFS='-:' read -ra arr <<< "$prevDateTime"
# print array values
declare -p arr
# This outputs
# declare -a arr='([0]="2015" [1]="05" [2]="21" [3]="10" [4]="24" [5]="28")'
#assign to other variables
prevYear=${arr[0]}
prevMonth=${arr[1]}
prevDay=${arr[2]}
prevHour=${arr[3]}
prevMinute=${arr[4]}
prevSecond=${arr[5]}
Fast solution using cut:
#!/bin/bash
prevDateTime=$(date +'%Y-%m-%d-%H:%M:%S')
echo "${prevDateTime}"
prevYear=`echo $prevDateTime | cut -d- -f1`
prevMonth=`echo $prevDateTime | cut -d- -f2`
prevDay=`echo $prevDateTime | cut -d- -f3`
prevHour=`echo $prevDateTime | cut -d- -f4 | cut -d: -f1`
prevMinute=`echo $prevDateTime | cut -d- -f4 | cut -d: -f2`
prevSecond=`echo $prevDateTime | cut -d- -f4 | cut -d: -f3`
echo "Year: $prevYear; Month: $prevMonth; Day: $prevDay"
echo "Hour: $prevHour; Minute: $prevMinute; Second: $prevSecond"

Resources