Find and replace date within a file - bash

My apologies if my title is not descriptive enough, I believe the following will be.
I have 3 files which are just plain text, within each file, is a date
Date: 2012-08-31 for example
I would like to get a command/script to find this and update to the current date, but the date will be ever changing and may not be known going in (without viewing the contents of the file
Knowing what the date is, its simple enough with sed, but how can I do this knowing the syntax of the line I want to modify, but not the specific values. ("Date: " at least is unchanging)

Assuming your date format is unchanging, and all three files are the only three text files in your PWD, you could use GNU sed like this:
sed -r 's/Date: [0-9]{4}-[0-9]{2}-[0-9]{2}/Date: 2012-09-01/g' *.txt

today=`date +%F`
sed -r -i '.bak' "s/Date: [0-9]{4}-[0-9]{2}-[0-9]{2}/Date: $today/g" file1 file2 file3

Related

Awk - filter only dates with certain format from text file

I have a .txt file with many lines of text on macOS. I would like to filter only dates and have them saved in order of appearance line by line in a new text file.
I am, however, not interested in all dates, only in those who are complete, looking like 02/03/2019, and those where the number of days is below 13, i. e. 01...12.
Then, I would like to have those dates removed where the number for the day and month are the same like 01/01/2019 and 02/02/2019 etc.
How can I achieve this with awk or similar software in bash?
If perl is a choice:
perl -ne 'print if m:(\d\d)/(\d\d)/(\d\d\d\d): && $1 < 13 && $1 != $2' dates.txt >newdates.txt
this assumes this format /dd/mm/yyyy
Note that I am using a m: : notation instead of the usual / / for regex matching. Thus I do not need to escape the / slashes in the date.
Deleting Dates Inside a Text File
The following command will delete all dates of the form✱ aa/bb/cccc where aa = bb < 13. The original file will be copied to yourFile.txt.bak as a backup and the new text with deleted dates will overwrite the old file.
sed -E -i.bak 's:\b(0[0-9]|1[0-2])/\1/[0-9]{4}\b::g' yourFile.txt
If you want to insert something instead of just deleting the dates you can do so by writing the replacement between the two ::. For instance sed … 's:…:deleted date:/g' … will replace each matching date with the text deleted date.
✱ Note that it doesn't matter for your criterion whether the date format is dd/mm/yyyy or mm/dd/yyyy since your are only interested in dates where dd and mm are equal.
Extracting Specific Dates From A Text File
If you do not want to delete, but only extract specific dates as mentioned in your comment, you can use the following command.
grep -Eo '\b([0-9]{2}/){2}[0-9]{4}\b' yourFile.txt | awk -F/ '$1<13 && $1!=$2'
This will extract all dates in dd/mm/yyyy (!) format where mm ≠ dd < 13. The dates are printed in order of appearance on stdin. If you want to save them to a file append > yourOutputFile.txt to the end of the command.

Unix Shell Scripting using Date Command

Ok, so i'm trying to write a scrpit to wc files using the date command. The format of the files, for example, goes like this: testfile20170104.gz.
Now the files are set up to have yesterday's date with the format yyyymmdd. So if today is 1/5/2017 the file will have the previous day of 1/4/2017 in the yyyymmdd format, as you see in the example above.
Normally to count the file all one needs to do is simply input: gzcat testfile20170104.gz|wc -l to get the word count.
However, what I want to do is run a script or even a for loop that gzcat the file but instead of having to copy and paste the filename in the command line, I want to use the date command to input put yesterday's date in the filename with the format of yyyymmdd.
So as a template something like this:
gzcat testfile*.gz|wc -l | date="-1 days"+%Y%m%d
Now I know what I have above is COMPLETELY wrong but you get the picture. I want to replace the '*' with the output from the date command, if that makes sense...
Any help will be much much appreciated!
Thanks!
You want:
filename="testfile$( date -d yesterday +%Y%m%d ).gz"
zcat "$filename"

Unix: Removing date from a string in single command

For satisfying a legacy code i had to add date to a filename like shown below(its definitely needed and cannot modify legacy code :( ). But i need to remove the date within the same command without going to a new line. this command is read from a text file so i should do this within the single command.
$((echo "$file_name".`date +%Y%m%d`| sed 's/^prefix_//')
so here i am removing the prefix from filename and adding a date appended to filename. i also do want to remove the date which i added. for ex: prefix_filename.txt or prefix_filename.zip should give me as below.
Expected output:
filename.txt
filename.zip
Current output:
filename.txt.20161002
filename.zip.20161002
Assumming all the files are formatted as filename.ext.date, You can pipe the output to 'cut' command and get only the 1st and 2nd fields :
~> X=filename.txt.20161002
~> echo $X | cut -d"." -f1,2
filename.txt
I am not sure that I understand your question correctly, but perhaps this does what you want:
$((echo "$file_name".`date +%Y%m%d`| sed -e 's/^prefix_//' -e 's/\.[^.]*$//')
Sample input:
cat sample
prefix_original.txt.log.tgz.10032016
prefix_original.txt.log.10032016
prefix_original.txt.10032016
prefix_one.txt.10032016
prefix.txt.10032016
prefix.10032016
grep from start of the string till a literal dot "." followed by digit.
grep -oP '^.*(?=\.\d)' sample
prefix_original.txt.log.tgz
prefix_original.txt.log
prefix_original.txt
prefix_one.txt
prefix.txt
prefix
perhaps, following should be used:
grep -oP '^.*(?=\.\d)|^.*$' sample
If I understand your question correctly, you want to remove the date part from a variable, AND you already know from the context that the variable DOES contain a date part and that this part comes after the last period in the name.
In this case, the question boils down to removing the last period and what comes after.
This can be done (Posix shell, bash, zsh, ksh) by
filename_without=${filename_with%.*}
assuming that filename_with contains the filename which has the date part in the end.
% cat example
filename.txt.20161002
filename.zip.20161002
% cat example | sed "s/.[0-9]*$//g"
filename.txt
filename.zip
%

Pipe last 11 characters in filename to a text file

Have a directory full of file names that end with .mp3 and have a code in it that i would like to pipe into a text file.
I need to get the last 11 characters before the .mp3 part of a file in a certain directory and pipe that into a text file (with bash on mac osx)
How do I accomplish this? With sed?
If I'm understanding correctly, you have a list of files with names like "abcdefghijklmnopqrstuvwxyz.mp3" and want to extract "pqrstuvwxyz". You can do this directly in bash without invoking any fancy sed business:
for F in *.mp3; do STRIP=${F/.mp3}; echo ${STRIP: -11}; done > list.txt
The first STRIP variable is the name of each file F with the .mp3 extension removed. Then you echo the last 11 characters and save to a file.
There's a nice page on bash substitutions here. sed is great but I personally find it's overkill for these simple cases.
Along with good above answers, can be done via awk
for f in `ls *.mp3`;
echo $f|awk -F. '{printf substr($1,length($1)-11,length($1)),$2;}'
done

Find text files in bash

I have a bunch of email's as text files in multiple directories under one directory. I am trying to write a script where I would type in a date as 3 separate command line arguments like so:
findemail 2015 20 04
the format being yyyy/dd/mm and it would bring up all filenames for emails that were sent on that day. I am unsure where to start for this though. I figured I could use find possibly but I am new to scripting so I am unsure. Any help would be greatly appreciated!
The timestamp in the email looks like:
TimeStamp: 02/01/2004 at 11:19:02 (still in the same format as the input)
grep -lr "$(printf "^TimeStamp: %02i/%02i/%04i" "$2" "$1" "$3")" path/to/directory
The regex looks for mm/dd/yyyy; swap the order of $1 and $2 if you want the more sensible European date order.
The command substitution $(command ...) runs command ... and substitutes its output into the command line which contains the command substitution. So we use a subshell which runs printf to create the regex argument to grep.
The -l option says to list the names of matching files; the -r option says to traverse a set of directories recursively. (If your grep is too pedestrian to have the -r option, it's certainly not hard to concoct a find expression which does the same. See e.g. here.)
The easiest thing to do would be to use a search utility such as grep. Grep has a very useful recursive option that allows searching for a string in all the files in a directory (and subdirectories) that's easy to use.
Assuming you have your timestamp in a variable called timestamp, then this would return a list of filenames that contain the timestamp:
grep -lr $timestamp /Your/Main/Directory/Goes/Here
EDIT: To clarify, this would only search for the exact string, so it needs to be in the exact same format as in the searched text.

Resources