Simplify complex command, put it into a variable - bash

date +'%A %B %d' | sed -e 's/\(^\|[^[:digit:]]\+\)0\+\([[:digit:]]\)/\1\2/g
I like the output of the above command, which strips leading zeroes off days of the month produced by the date command, in the case of numerals less than 10. It's the only way I've thus far found of producing single digit dates from the date command's output for the day of the month, which otherwise would be 01, 02, 03, etc.
A couple of questions in this regard. Is there a more elegant way of accomplishing the stated goal of stripping off zeroes? I do know about date's %e switch and would like to use it, but with numerals 10 and greater it has the undesirable effect of losing the space between the month name and the date (so, July 2 but July10).
The second question regards the larger intended goal of arriving at such an incantation. I'm putting together a script that will scrape some data from a web page. The best way of locating the target data on the page is by searching on the current date. But the site uses only single digits for the first 9 days of the month, thus the need to strip off leading zeroes. So what's the best way of getting this complex command into a variable so I can call it within my script? Would a variable within a variable be called for here?
RESOLUTION
I'll sort of answer my own question here, though it is really input from Renaud Pacalett (below) that enabled me to resolve the matter. His input revealed to me that I'd not understood very well the man page, particularly the part where is says "date pads numeric fields with zeroes," and below that where it is written "- (hyphen) do not pad the field." Had I understood better those statements, I would have realized that there is no need for the complex sed line through which I piped the date output in the title of this posting: had I used there %-d instead of just %d there would have been no leading zeroes in front of numerals less than 10 and so no need to call sed (or tr, as suggested below by LMC) to strip them off. In light of that, the answer to the second question about putting that incantation into a variable becomes elementary: var=$(date +'%A %B %-d') is all that is needed.
I may go ahead and mark Renaud Pacalet's response as the solution since, even though I did not implement all of his suggestions into the latest incarnation of my script, it proved crucial in clarifying key requirements of the task.

If your date utility supports it (the one from GNU coreutils does) you can use:
date +'%A %B %-d'
The - tells date to not pad the numeric field. Demo:
$ date -d"2021/07/01" +'%A %B %-d'
Thursday July 1
Not sure I understand your second question but if you want to pass this command to a shell script (I do not really understand why you would do that), you can use the eval shell command:
$ cat foo.sh
#!/usr/bin/env bash
foo="$(eval "$1")"
echo "$foo"
$ ./foo.sh 'date -d"2021/07/01" +"%A %B %-d"'
Thursday July 1
Please pay attention to the double (") and simple (') quotes usage. And of course, you will have to add to this example script what is needed to handle errors, avoid misuses...
Note that many string comparison utilities support one form or another of extended regular expressions. So getting rid of these leading zeros or spaces can be as easy as:
grep -E 'Thursday\s+July\s+0*1' foo.txt
This would match any line of foo.txt containing
Thursday<1 or more spaces>July<1 or more spaces><0 or more zeros>1

Related

zsh on macOS date modify output of given date (without script)

I‘m aware of date +%u to get the day of the week for today.
I‘d like to get that integer for any arbitrary date i input - if possible in the format I choose (e.g. %YYmmdd)
ok, found it finally:
date -j -f %Y%m%d +%u 20200910
this is, because date on macOS doesn't take a switch for putting in custom date (fyi for those folks, how try to make -v work, like me^^)
in addition, -f affects only input format (it's literally the second word in the man page, but I managed to overlook more than once)
-j is needed to use -f without setting the date.
hope this will spare someone time in the future ;)
edit:
it seems to be important, to specify input format before output format (see comment from #chepner below)
(also be careful with quotes)
$ date +%u -d "2020-09-10"
4

Swap first and last four characters in a filename

StackOverflow.
I have a colleciton of notes from work. I keep them as markdown files, and had been formatting them with the date and year - for example, today's is titled 06132017.md
I am coming up on a year at work, so I have quite a few of these files. I wish to change the naming convention from month/day first to year first, so that I can sort them alphabetically and easily find dates I need.
So 06132017.md would become 20170613.md - this would keep 2016 and 2017 from mixing in aplha order. Is there a command I can run on a folder to do this?
If you have the Perl rename utility, it's rather simple to do:
$ prename 's/^(....)(....)(\.md)$/$2$1$3/' *.md
06132017.md renamed as 20170613.md
The dots match any character, the parenthesis group, and $N on the replacement side inserts the characters captured in the groups.
Or just in Bash:
$ for x in ????????.md ; do mv -v "$x" "${x:4:4}${x:0:4}.md" ; done
'06132017.md' -> '20170613.md'
${var:n:m} takes a substring of length m, starting at position n from variable var.

How to get the last time a file was modified in Unix

I am trying to get the last time the date a file was modified. I used a variable for date and a variable for time.
This will get the date and time but I want to use -r using the date command to make a reflection of when the date was last modified. Just not sure how I go about using it in my variables.
How would I go about doing this?
Here are my variables:
DATE="$(date +'%m/%d/%Y')"
TIME="$(date +'%H:%M')"
I tried putting the -r after and before the time and date.
Though people might tell you, you should not parse the output of ls, simply that can easily break if your file name contains tabs, spaces, line breaks, your user decides to simply specify a different set of ls options, the ls version you find is not behaving like you expected...
Use stat instead:
stat -c '%Y'
will give you the seconds since epoch.
Try
date -d "#$(stat -c '%Y' $myfile)" "+%m/%d/%Y"
to get the date, and read through man date to get the time in the format you want to, replacing '%F' in the command line above:
date -d "#$(stat -c '%Y' $myfile)" "+%H:%M"
EDIT: used your formats.
EDIT2: I really don't think your date format is wise, because it's just so ambiguous for anyone not from the US, and also it's not easily sortable. But it's a cultural thing, so this is more of a hint: If you want to make your usable for people from abroad, either use Year-month-day as format, or get the current locale's setting to format dates.
I think you are looking for
ls -lt myfile.txt
Here in 6th column you will see when file was modified.
Or you could use stat myfile.txt to check the modified time of a file.
I know this is a very old question, but, for the sake of completeness, I'm including an additional answer here.
The original question does not specify the specific operating system. stat differs significantly from SysV-inspired Unixes (e.g. Linux) and BSD-inspired ones (e.g. Free/Open/NetBSD, macOS/Darwin).
Under macOS Big Sur (11.5), you can get the date of a file with a single stat command:
stat -t '%m/%d/%Y %H:%M' -f "%Sm" myfile.txt
will output
04/10/2021 23:22
for April 10, 2021.
You can easily put that in two commands, one for the date, another for the time, of course, to comply with the original question as formulated.
Use GNU stat.
mtime=$(stat --format=%y filename)

Error while extracting data from log file

I am running awk command to extract data from log file to calculate last 15 minutes log using below command and now i am getting bellow error:
awk '$0>=$from' from=$(`date -u +"####<%d-%b-%Y %H:%M:%S o'clock GMT>"-15min`) test.log
Error:
date: 0551-402 Invalid character in date/time specification.
Usage: date [-u] [+"Field Descriptors"]
awk: 0602-562 Field $() is not correct.
The input line number is 1. The file is test.log.
The source line number is 1.
Can anyone see what the problem is?
I believe you mean
awk '$0 >= from' from=$(date -u -d -15min "+####<%d-%b-%Y %H:%M:%S o'clock GMT>") test.log
$from in awk code does not mean the value of from but the fromth field. This does not make any sense if field is not a number.
the -15min in your date call are part of the format specifier, not the date spec.
Either backticks or $(), not both at the same time. Unless you want to run the output of date as a command and use the output of that.
By the way, I suspect that the lexicographical comparison of date strings formatted this way will not yield the result you want. It will not result in later dates being considered greater than earlier ones in all cases -- particularly at the end/beginning of months. 28-Feb is lexicographically greater than 01-Mar.
Addendum: Ah, I figured this seemed familiar. I left a solution to your previous question that does not have this problem before it was closed as a duplicate of something that doesn't really work for this case.

Cshell Script date issue

Is there a way to add date in the name of the file... we can add current date in this manner date '+%Y%m%d' but i want to add "filename_date_1-2-2011_thru_31-2-2011.txt" Is it possible to do that??????????
If you have a sufficiently advanced version of the date command and you know a Unix timestamp for the start and end dates, then you can use:
(MacOS X) date -r 1234567890 "+%d-%m-%Y" to obtain 13-02-2009.
(GNU) date -d 2/13/2009 "+%d-%m-%Y" to obtain 13-02-2009 again.
If you don't want the leading zeroes on the day of month, then you need to use '%e` instead of '%d' on Linux (but that puts a space in place of the zero). It is not clear that there's a format specifier for day-of-month without a leading zero on MacOS X; nor is it clear that there's a way to format month of year as a single-digit number for January to September on either platform.
You get the format into your C shell script using back-ticks around the date commands.
Consider reading Csh Programming Considered Harmful and heeding its advice.

Resources