Shell script to fetch log (json format) file between date and timestamp - shell

The log file folder structure is \Mainfolder\folder1\year(2020)\month(07)\date(24)*.json.
Ex: \Mainfolder\folder1\2020\07\24\filename.json.
The .json file is getting created every hour, like 00:00:00_00:59:59.json, 01:00:00_01:59:59.json and so on.
I have to search under the .json file with following inputs.
My current inputs are keyword, start date. Currently I'm taking that Date, and keyword and able to get the output in a file.
Current script for your reference:
#!/bin/bash
set +x
DTE=$(date "+%d-%m-%Y-v%H%m%s")
Date=$1 #yyyy/mm/dd
Keyword=$2 #keyword in string
Start_Time=$3 #hh:mm
End_Time=$4 #hh:mm
BKT=bucketpath/mainfolder/
output=$(gsutil cat -h gs://bucketpath/mainfolder/"$Date"/* | egrep "$Keyword")
echo $output >> $"/tmp/folder/logoutput-$DTE"
gsutil cp -r /tmp/folder/logoutput-$DTE gs://bucketpath/mainfolder/
I have to add end date, Start_Time & End_Time and search in the .json file and get the output in a file like above.
I tried to use awk & sed, but i'm unable to get the output.
Could anyone help me on this script please.
Thanks in advance.

I prepared following script to collect the logs between date and timestamp along with keyword. My log file is in .json format.
The reason for posting here is, it might help someone who is looking for similar script.
#!/bin/bash
set +x
DTE=$(date "+%d-%m-%Y-v%H%m%s")
startdate=$1
enddate=$2
start_Time=$3
end_Time=$4
keyword=$5
BKT=storage/folder
i=$start_time
i1=$(sed 's/.\{3\}$//' <<< "$i")
j=$end_time
j1=$(sed 's/.\{3\}$//' <<< "$j")
curr="$startdate"
while true; do
echo "$curr"
[ "$curr" \< "$enddate" ] || break
output=$(gsutil cat -h gs://storage/folder/"$curr"/"$i1:00:00_$j1:59:59*" | sed -n '/"timestamp":"[^"]*T'$i':/,/"timestamp":"[^"]*T'$j':/p' | grep "$keyword")
echo $output >> $"/tmp/folder/mylog-$DTE"
curr=$( date +%Y/%m/%d --date "$curr +1 day" )
done
gsutil cp -r /tmp/folder/mylog-$DTE gs://storage/folder/

Related

How to send shell script output in a tablular form and send the mail

I am a shell script which will give few lines as a output. Below is the output I am getting from shell script. My script flow is like first it will check weather we are having that file, if I am having it should give me file name and modified date. If I am not having it should give me file name and not found in a tabular form and send email. Also it should add header to the output.
CMC_daily_File.xlsx Not Found
CareOneHMA.xlsx Jun 11
Output
File Name Modified Date
CMC_daily_File.xlsx Not Found
CareOneHMA.xlsx Jun 11
UPDATE
sample of script
#!/bin/bash
if [ -e /saddwsgnas/radsfftor/coffe/COE_daily_File.xlsx ]; then
cd /sasgnas/radstor/coe/
ls -la COE_daily_File.xlsx | awk '{print $9, $6"_"$7}'
else
echo "CMC_COE_daily_File.xlsx Not_Found"
fi
Output
CMC_COE_daily_File.xlsx Jun_11
I thought I might offer you some options with a slightly modified script. I use the stat command to obtain the file modification time in more expansive format, as well as specifying an arbitrary, pre-defined, spacer character to divide the column data. That way, you can focus on displaying the content in its original, untampered form. This would also allow the formatted reporting of filenames which contain spaces without affecting the logic for formatting/aligning columns. The column command is told about that spacer character and it will adjust the width of columns to the widest content in each column. (I only wish that it also allowed you to specify a column divider character to be printed, but that is not part of its features/functions.)
I also added the extra AWK action, on the chance that you might be interested in making the results stand out more.
#!/bin/sh
#QUESTION: https://stackoverflow.com/questions/74571967/how-to-send-shell-script-output-in-a-tablular-form-and-send-the-mail
SPACER="|"
SOURCE_DIR="/saddwsgnas/radsfftor/coe"
SOURCE_DIR="."
{
printf "File Name${SPACER}Modified Date\n"
#for file in COE_daily_File.xlsx
for file in test_55.sh awkReportXmlTagMissingPropertyFieldAssignment.sh test_54.sh
do
if [ -e "${SOURCE_DIR}/${file}" ]; then
cd "${SOURCE_DIR}"
#ls -la "${file}" | awk '{print $9, $6"_"$7}'
echo "${file}${SPACER}"$(stat --format "%y" "${file}" | cut -f1 -d\. | awk '{ print $1, $2 }' )
else
echo "${file}${SPACER}Not Found"
fi
done
} | column -x -t -s "|" |
awk '{
### Refer to:
# https://man7.org/linux/man-pages/man4/console_codes.4.html
# https://www.ecma-international.org/publications-and-standards/standards/ecma-48/
if( NR == 1 ){
printf("\033[93;3m%s\033[0m\n", $0) ;
}else{
print $0 ;
} ;
}'
Without that last awk command, the output session for that script was as follows:
ericthered#OasisMega1:/0__WORK$ ./test_55.sh
File Name Modified Date
test_55.sh 2022-11-27 14:07:15
awkReportXmlTagMissingPropertyFieldAssignment.sh 2022-11-05 21:28:00
test_54.sh 2022-11-27 00:11:34
ericthered#OasisMega1:/0__WORK$
With that last awk command, you get this:

Use awk to analyze csv file - combined with shell 'date' command in awk

I have a .csv file which has dates and the answer about enjoyable or not:
2019-04-1,enjoyable
2019-04-2,unenjoyable
2019-04-3,unenjoyable
2019-04-4,enjoyable
2019-04-5,unenjoyable
2019-04-6,unenjoyable
2019-04-7,enjoyable
2019-04-8,unenjoyable
2019-04-9,unenjoyable
2019-04-10,enjoyable
2019-04-11,enjoyable
2019-04-12,enjoyable
2019-04-13,unenjoyable
2019-04-14,enjoyable
2019-04-15,unenjoyable
2019-04-16,unenjoyable
2019-04-17,unenjoyable
2019-04-18,enjoyable
2019-04-19,unenjoyable
2019-04-20,unenjoyable
2019-04-21,unenjoyable
2019-04-22,unenjoyable
2019-04-23,unenjoyable
2019-04-24,unenjoyable
2019-04-25,unenjoyable
2019-04-26,unenjoyable
What I want to do is to print the day of the week in the third column seperate by ',' like this:
2019-04-1,enjoyable,2
2019-04-2,unenjoyable,3
I tried:
dates=$(awk '{FS=","}{print $1,$2}' weather_stat.csv')
weeks=$(
for vars in $dates[first_row]
do
echo $(date -j -f '%Y-%m-%d' $vars "+%w")
done
)
merge($dates,$weeks)
The first part of the code works without any problem, but in the second part, I am confused about how to get the data in the first row (so I use dates[first_row] to mean the first row in dates variable) from the variable "dates" so we can apply 'date' method on it
And for the third part, I want to merge these two tables together. I found the 'join' function but it seem to work on two files instead of two variables(I don't want to have any new files during the process)
Could anyone tells me how to get the rows in a variable instead of a file in shell and the way to merge two table-like variables?
As you're learning shell scripting, here's some code to study:
to read your csv file, and get the weekday number for each date in the file:
while IFS=, read -r date rest; do echo "$date,$(date -d "$date" +%w)"; done < file.csv
to join the output of that command with your file:
weekdays=$(while IFS=, read -r date rest; do echo "$date,$(date -d "$date" +%w)"; done < file.csv)
join -t, file.csv <(echo "$weekdays")
or, without needing to store the result in an intermediate variable
join -t, file.csv <(
while IFS=, read -r date rest; do echo "$date,$(date -d "$date" +%w)"; done < file.csv
)
The newlines within the <() are not necessary, but useful for maintainable code.
However, you can see that this is less efficient because you have to process the file twice. With awk you only have to read through the file once.
With GNU awk:
awk' BEGIN{FS=OFS=","}
{ split($1,a,"-")
t=sprintf("%0.4d %0.2d %0.2d 00 00 00",a[1],a[2],a[3]);
print $0,strftime("%w",mktime(t))
}' file.csv
With only your Bourne shell, so less efficient than awk if you have a lot of lines in your CSV file:
while IFS=, read date enjoy; do
date -d "$date" +"$date,$enjoy,%w"
done < your.csv

output a file with a variable name in shell

So I am trying to output a file with the name of like: lastlogin-"yyyymmdd" where it contains the current date.
I figured out the date should be : date +"%Y%m%d" and I tried to do a variable
now = date +"lastlogin-%Y%m%d.txt"
filename = ${now}
xxxxx > ${filename}
but nothing seems to work
Please help
Use command substitution:
lastlogin-"$(date '+%Y%m%d')".txt
To save in a variable:
filename="lastlogin-"$(date '+%Y%m%d')".txt"
and then do:
echo 'foobar' >"$filename"
You should use $() for command execution and storage of result:
now=$(date +"lastlogin-%Y%m%d.txt")

Grepping a specific string from a file in script

I have following file:(A sample file with filename: 2015_09_22_processedPartnumList.txt, Location: /a/b/c/itemreport)
DataLoader_trace_2015_09_22_02_01_32.0956.log:INFO: 2015-09-22
Data Processing Starts : 12345678
I just want to get all the ids from the above file i.e. 12345678 .... (each id in a separate line, not comma separated) in a file /a/b/c/d/ids_date +%d_%m_%Y_%H_%M_%S.log
I have written the following script, but the file I am getting is empty. Without showing any exception or anything. So, it is very difficult for me to identify the errors. Please tell me what is wrong in the script.
LOGDIR=/a/b/logdir
tr=`date +%p`
echo $tr
if [ $tr = "PM" ];
then
date=`date +%Y-%m-%d`
echo "considering today's date for grepping logs"
else
date=`date -d '1 day ago' +%Y-%m-%d`
echo "considering yesterday's date for grepping logs as job run is delayed"
fi
ITEM_FILE=/a/b/c/d/ids_`date +%d_%m_%Y_%H_%M_%S`.log
After implementing grep in PCRE, I am getting this and not any ids are being copied into the new file.
If your grep supports PCRE, you can do:
grep -Po '.*:\s\K\d+$' /a/b/c/itemreport/2015_09_22_processedPartnumList.txt \
>/apps/feeds/out/catalog/ItemPartnumbers_"$(date '+%d_%m_%Y_%H_%M_%S')".log
.*:\s will match upto the space after :, \K will discard the match
\d+$ will match our desired portion i.e. the digits till the end of the line
Example:
% grep -Po '.*:\s\K\d+$' 2015_09_22_processedPartnumList.txt \
>ItemPartnumbers_"$(date '+%d_%m_%Y_%H_%M_%S')".log
% cat ItemPartnumbers_09_11_2015_11_30_49.log
13982787
14011550
13984790
13984791
14176509
14902623
14924193
14924194
13982787
46795670
46795671
That's not very good solution, but it's working.
cat your\ file | cut -d ':' -f2-2 | tr -d INFO

Bash script to convert a date and time column to unix timestamp in .csv

I am trying to create a script to convert two columns in a .csv file which are date and time into unix timestamps. So i need to get the date and time column from each row, convert it and insert it into an additional column at the end containing the timestamp.
Could anyone help me? So far i have discovered the unix command to convert any give time and date to unixstamp:
date -d "2011/11/25 10:00:00" "+%s"
1322215200
I have no experience with bash scripting could anyone get me started?
Examples of my columns and rows:
Columns: Date, Time,
Row 1: 25/10/2011, 10:54:36,
Row 2: 25/10/2011, 11:15:17,
Row 3: 26/10/2011, 01:04:39,
Thanks so much in advance!
You don't provide an exerpt from your csv-file, so I'm using this one:
[foo.csv]
2011/11/25;12:00:00
2010/11/25;13:00:00
2009/11/25;19:00:00
Here's one way to solve your problem:
$ cat foo.csv | while read line ; do echo $line\;$(date -d "${line//;/ }" "+%s") ; done
2011/11/25;12:00:00;1322218800
2010/11/25;13:00:00;1290686400
2009/11/25;19:00:00;1259172000
(EDIT: Removed an uneccessary variable.)
(EDIT2: Altered the date command so the script actually works.)
this should do the job:
awk 'BEGIN{FS=OFS=", "}{t=$1" "$2; "date -d \""t"\" +%s"|getline d; print $1,$2,d}' yourCSV.csv
note
you didn't give any example. and you mentioned csv, so I assume that the column separator in your file should be "comma".
test
kent$ echo "2011/11/25, 10:00:00"|awk 'BEGIN{FS=OFS=", "}{t=$1" "$2; "date -d \""t"\" +%s"|getline d; print $1,$2,d}'
2011/11/25, 10:00:00, 1322211600
Now two imporvements:
First: No need for cat foo.csv, just stream that via < foo.csv into the while loop.
Second: No need for echo & tr to create the date stringformat. Just use bash internal pattern and substitute and do it inplace
while read line ; do echo ${line}\;$(date -d "${line//;/ }" +'%s'); done < foo.csv

Resources