changing the date format in shell script - shell

I have a string and I need to separate the country name and date.
# echo 'india16-Feb-2013-20-33.sql' | sed 's/[0-9][0-9]//' | awk -F"-" '{print $1}'
india
# echo 'india16-Feb-2013-20-33.sql' | sed 's/india//' | awk -F"." '{print $1}'
16-Feb-2013-20-33
1) Is the above sed + awk correct? Is there any better way?
2) How do I format the date as 2013-02-16 20:33:00
I got the string (16-Feb) mentioned above using the following command. But I do not know how to change it back.
date '+%d-%b-%Y-%H-%M'

I couldn't get the sed with date versions working on osx so I did a Python version.
import datetime
import re
datestr = 'india16-Feb-2013-20-33.sql'
(country, date) = re.findall('(.*?)(\d{2}-.{3}-\d{4}-\d{2}-\d{2}).*', datestr)[0]
dt = datetime.datetime.strptime(date, "%d-%b-%Y-%H-%M")
print "country=", country
print "dt=", dt
Gives:
country= india
dt= 2013-02-16 20:33:00

I am starting to love sed
$ cat a.txt
india16-Feb-2013-20-33.sql
$ sed 's/[0-9].*//' a.txt
india
$ sed 's/[a-z]*//; s/-/ /3; s/-/:/3; s/.sql//' a.txt | xargs -0 date '+%F %T' -d
2013-02-16 20:33:00

Using sed and a single substitution:
sed 's/.*\([0-9]\{2\}-[A-Z][a-z]\{2\}-[0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\).*/date -d "\1 \2\3" +"%F %T"/ge'
Personally, I find it's a little bit easier on the eyes using GNU sed:
sed -r 's/.*([0-9]{2}-[A-Z][a-z]{2}-[0-9]{4})-([0-9]{2})-([0-9]{2}).*/date -d "\1 \2\3" +"%F %T"/ge'
Results:
2013-02-16 20:33:00

Related

Covert date and time to weekday [YY-MM-DDThh:mm:ss to weekends]

i have data which is csv as below, i need to create weekday columns based on "date" column.
date,user,status
2022-10-31T06:28:16+09:00,JACK,login
2022-10-27T11:43:36+09:00,PETER,login
2022-10-26T07:11:19+09:00,MIKE,notlogin
2022-10-22T23:42:46+09:00,KANE,login
2022-10-21T00:12:38+09:00,VINI,notlogin
i required to add one more column as weekday , 2022-10-31 is monday .. as shown below
date,user,status,day,weekday
2022-10-31T06:28:16+09:00,JACK,login,monday
2022-10-27T11:43:36+09:00,PETER,login,thursday
2022-10-26T07:11:19+09:00,MIKE,notlogin,wednesday
2022-10-22T23:42:46+09:00,KANE,login,saturday
2022-10-21T00:12:38+09:00,VINI,notlogin,monday
Taken from comments
I have tried using
$ cat data | awk -F "," '{print $1}' | awk 'NR>1' | awk -F "T" '{print $1}'
but im not much aware where to pass date -d YY-mm-dd "+%A" command
Using GNU sed
$ sed -E '/^[0-9]/{s/([^T]*).*/echo &,$(date -d '\\1' +'%A')/e};s/,[[:alpha:]]+$/\L&/;1s/$/,day,weekday/' input_file
date,user,status,day,weekday
2022-10-31T06:28:16+09:00,JACK,login,monday
2022-10-27T11:43:36+09:00,PETER,login,thursday
2022-10-26T07:11:19+09:00,MIKE,notlogin,wednesday
2022-10-22T23:42:46+09:00,KANE,login,saturday
2022-10-21T00:12:38+09:00,VINI,notlogin,friday

Remove everything before a string with bash?

I'm doing this with ffmpeg :
ffmpeg -i /Users/petaire/GDrive/Taff/ASI/Bash/testFolder/SilenceAndBlack.mp4 -af silencedetect=d=2 -f null - 2>&1 | grep silence_duration
And my output is :
[silencedetect # 0x7f9e6940eba0] silence_end: 25.92 | silence_duration: 25.936
But I only want to keep the duration number, so I'm trying to remove everything before the last number.
I've never understood anything about sed/awk & co, so I dont know what is the best way to do that. I thought grep would be powerful enough, but it doesn't seems so.
Any idea?
Using awk to print the last field:
$ awk '{print $NF}'
Test it:
$ echo "[silencedetect # 0x7f9e6940eba0] silence_end: 25.92 | silence_duration: 25.936"| awk '{print $NF}'
25.936
or use sed to replace everything up to last space with nothing:
$ ... | sed 's/.* //'
you can change your grep command to
grep -oP '(?<=silence_duration: )\S+'
which will print the next field to the searched one.
to remove everything before the last number
you can use
grep -o "[^ ]*$"
Another option, grep -o with cut:
$ echo '[silencedetect # 0x7f9e6940eba0] silence_end: 25.92 | silence_duration: 25.936' \
| grep -o 'silence_duration: [0-9]*\.[0-9]*' | cut -d ' ' -f 2
25.936

grep 2 elements in a line and print them

Here is my issue, i have a file with the entries, i would like to get just the date + the last command after the last "]: "
Aug 17 14:25:17 snaper[22134]: [ip:10.1.15.245 37985 10.1.15.18 22 uid:10000 sid:21680 tty: cwd:/data/www/hybris/hybris/bin/platform filename:/bin/ps]: /bin/ps -p 6763
How can i get it when i cat the file ?
I can get the date with:
awk '{print $1,$2,$3}'
and the last command with :
awk -F': ' '{print $NF}'
But how to combine them to get it in a single line ?
I'm not awk limited, any sed grep or other command is ok for me :)
Thanks in advance
Just remove everything between the date and the last command:
sed 's/^\(... .. ..:..:..\).*: /\1 /'
Simple solution using AWK
$awk '{print $1,$2,$3, $(NF-2), $(NF-1), $NF }' file
Aug 17 14:25:17 /bin/ps -p 6763
Using GNU grep
grep -oP '^.{15}|.*\]: \K.*' file | paste - -
Possible use tee for use 1 output to 2 commands:
echo 'Aug 17 14:25:17 snaper[22134]: [ip:10.1.15.245 37985 10.1.15.18 22 uid:10000 sid:21680 tty: cwd:/data/www/hybris/hybris/bin/platform filename:/bin/ps]: /bin/ps -p 6763' | tee >(awk -F': ' '{print $NF}') | awk '{print $1,$2,$3}' | tr '\n' ' '
and we have output as:
Aug 17 14:25:17 /bin/ps -p 6763
$ s="Aug 17 14:25:17 snaper[22134]: [ip:10.1.15.245 37985 10.1.15.18 22 uid:10000 sid:21680 tty: cwd:/data/www/hybris/hybris/bin/platform filename:/bin/ps]: /bin/ps -p 6763"
Use sed to achieve your goal,
$ sed -r 's/(^.*:[0-9]{2}) .*]:/\1/' <<< "$s"
Try following solutions too. Considering your Input_file will be having same data as shown sample.
Solution 1st: Using simple cut command.
cut -d" " -f1,2,3,14,15,16 Input_file
Solution 2nd: using awk command where I am making string snaper and ]: as field separators.
awk -F' snaper|]:' '{print $1,$4}' Input_file
Solution 3rd: making record separator as space and then printing only those lines which we need as per OP's request.
awk -v RS=" " 'NR<4||NR>13{printf("%s%s",$0,NR<3||NR<16?" ":"")}' Input_file
Solution 4th: Substituting everything from snap to till : and get whatever is OP's request.
awk '{sub(/snaper\[.*\]: /,"");print}' Input_file
Solution 5th: Using --re-interval here(as I have old version of awk) you could remove it if you latest awk version in your system too.
awk --re-interval '{match($0,/.*[0-9]{2}:[0-9]{2}:[0-9]{2}/);print substr($0,RSTART,RLENGTH),$(NF-2),$(NF-1),$NF}' Input_file
Solution 6th: using sed and substituting everything till snaper and then everything till colon and printing the match only.
sed 's/\(.[^s]*\)\(.*:\)\(.*\)/\1\3/' Input_file

Using and manipulating date variable inside AWK

I assume that there may be a better way to do it but the only one I came up with was using AWK.
I have a file with name convention like following:
testfile_2016_03_01.txt
Using one command I am trying to shift it by one day testfile_20160229.txt
I started from using:
file=testfile_2016_03_01.txt
IFS="_"
arr=($file)
datepart=$(echo ${arr[1]}-${arr[2]}-${arr[3]} | sed 's/.txt//')
date -d "$datepart - 1 days" +%Y%m%d
the above works fine, but I really wanted to do it in AWK. The only thing I found was how to use "date" inside AWK
new_name=$(echo ${file##.*} | awk -F'_' ' {
"date '+%Y%m%d'" | getline date;
print date
}')
echo $new_name
okay so two things happen here. For some reason $4 also contains .txt even though I removed it(?) ##.*
And the main problem is I don't know how to pass the variables to that date, the below doesn't work
`awk -F'_' '{"date '-d "2016-01-01"' '+%Y%m%d'" | getline date; print date}')
ideally I want 2016-01-01 to be variables coming from the file name $2-$3-$4 and substract 1 day but I think I'm getting way too many single and double quotes here and my brain is losing..
Equivalent awk command:
file='testfile_2016_03_01.txt'
echo "${file%.*}" |
awk -F_ '{cmd="date -d \"" $2"-"$3"-"$4 " -1 days\"" " +%Y%m%d";
cmd | getline date; close(cmd); print date}'
20160229
WIth GNU awk for time functions:
$ file=testfile_2016_03_01.txt
$ awk -v file="$file" 'BEGIN{ split(file,d,/[_.]/); print strftime(d[1]"_%Y%m%d."d[5],mktime(d[2]" "d[3]" "d[4]" 12 00 00")-(24*60*60)) }'
testfile_20160229.txt
This might work for you:
file='testfile_2016_03_01.txt'
IFS='_.' read -ra a <<< "$file"
date -d "${a[1]}${a[2]}${a[3]} -1 day" "+${a[0]}_%Y%m%d.${a[4]}"

bash more effective use of sed / awk

I am looking for a more efficient to use the following string to get the desired result as a one liner
date -d #1381219358 | sed 's/\ \ /\ /g' | sed 's/[:\ ]/-/g' | sed 's/2013/13/' | awk -F '-' '{print $4"-"$5"-"$6"-"$2"-"$3"-"$8}'
The desired result output is as follows:
04-02-38-Oct-8-13
Any help would be appreciated
You can format the output directly, like this:
date -d #1381219358 +"%H-%M-%S-%b-%d-%y"
10-02-38-Oct-08-13
I'm not sure if you need sed or awk for this. You can format the output using date.
Try saying:
date -d #1381219358 +%H-%M-%S-%b-%d-%y

Resources