strftime() replace %OB for windows - windows

Here is my code:
strftime('%OB %Y', time());
This line return false. How do I get this line for windows?
Thanks!

If you read the documentation, %B does not allow a prefix, so drop the O:
'%B %Y'

Related

Windows batch loop saving results into a file line by line

I run a command on each file within a folder and I would like to write the result line by line in a text file
for %r in (*) do (magick identify -format "%f, %w, %h" %r >> out.txt)
(it returns the image name and its size)
Which gives:
1048.tif, 3175, 2802,1049.tif, 3175, 2802...
I would like something like
> 1048.tif, 3175, 2802
> 1049.tif, 3175, 2802...
I tried with echo before magick identify but it writes the command and not the result
With ImageMagick you can try putting a "\n" in your format string...
... -format "%f, %w, %h\n" ...
That will insert a line break after the height.

How to rename multiple files in bash by moving/replacing characters and converting date format in file name? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In my log directory I have 600+ log files that have a naming scheme as:
abc.log.DDMMMYYYY
For example:
abc.log.01Nov2017
abc.log.02Nov2017
abc.log.10Dec2017
abc.log.21Jan2018
abc.log.22Jan2018
abc.log.23Jan2018
I am looking a way to rename all these files as...
YYYY-MM-DD.abc.log
The month name in file name must convert to month number. (Jan = 01, Feb = 02 ...)
For example:
2017-11-01.abc.log
2017-11-02.abc.log
2017-12-10.abc.log
2018-01-21.abc.log
2018-01-22.abc.log
2018-01-23.abc.log
How can I rename all these files in bash?
#!/bin/bash -e
# Create kludged associative array (for bash versions prior to 4 -- 4 has
# built-in associative arrays).
i=0
for Month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec; do
let i=i+1
# Pad with leading zero and then take last two characters.
Padded=0$i
eval Key$Month=${Padded: -2:2}
done
# Iterate on all files whose names match *.log.*.
for File in *.log.*; do
# Match to pattern with expected date format.
if [[ ! $File =~ ^(.*)\.log\.([0-3][0-9])([A-Z][a-z][a-z])([0-9]{4})$ ]]; then
echo "$File does not match pattern."
else
# Extract matched name and date.
Name=${BASH_REMATCH[1]}
Day=${BASH_REMATCH[2]}
InMonth=${BASH_REMATCH[3]}
Year=${BASH_REMATCH[4]}
# Convert month name abbreviation to month number.
# number %m, day number %d).
eval OutMonth=\$Key$InMonth
NewName="$Year-$OutMonth-$Day.$Name.log"
# Inform user.
echo "Will rename $File to $NewName."
# Rename.
mv "$File" "$NewName"
fi
done
This is locale sensitive, of course. And it expects four-digit dates, so it will break in the year 10,000. And you could add various error checks.
As you have requested batch-file solution, here is a possible solution:
#echo off
setlocal EnableDelayedExpansion
rem Set Month Numbers:
set "Jan=01"
set "Feb=02"
set "Mar=03"
set "Apr=04"
set "May=05"
set "Jun=06"
set "Jul=07"
set "Aug=08"
set "Sep=09"
set "Oct=10"
set "Nov=11"
set "Dec=12"
rem Main Loop to rename files:
for %%A IN (*.log.*) do (
for /f "delims=." %%B IN ("%%~xA") do (
set "extension=%%B"
call ren "%%A" "!extension:~5!-%%!extension:~2,-4!%%-!extension:~0,-7!.abc.log"
)
)
Let me explain break it down:
First we set MMM variables to the requested format: MM.
Now, we come to the main loop.
We loop through all files in the current folder (%cd%) which contain .log.. We do this using * wildcard.
Then, we loop in the extension of each file found.
We set the extension (without the dot (.)) in the variable extension.
After that, we rename file found in first loop (%%A) with the strings found and analyzed.
To better understand how these commands work, I suggest you to open a cmd and type the following commands:
set /?
rem /?
for /?
ren /?
Some interesting references for further reading:
https://ss64.com/nt/for.html
https://ss64.com/nt/ren.html
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?
https://www.dostips.com/DtTipsStringManipulation.php#Snippets.MidString
https://www.robvanderwoude.com/battech_wildcards.php
What does "&&" in this batch file?
https://ss64.com/nt/syntax-redirection.html
If gawk is available, please try:
#!/bin/bash
for f in abc.log.*; do echo "$f"; done | awk 'BEGIN {
str="JanFebMarAprMayJunJulAugSepOctNovDec"
for (i=1; i<=12; i++) s2n[substr(str, i*3-2, 3)] = sprintf("%02d", i)
}
{if (match($0, "(.+)\\.([0-9]{2})([A-Z][a-z]{2})([0-9]{4})", a))
printf("%s%c%04d-%02d-%02d.%s%c", $0, 0, a[4], s2n[a[3]], a[2], a[1], 0)
}
' | xargs -0 -n 2 mv
It maps the month name to month number via an array s2n.
The awk script outputs pairs of filenames like: abc.log.01Nov2017, 2017-11-01.abc.log... The filenames are separated by a null character.
The xargs reads the passed filenames two by two and performs mv command on
them.

Customise My zsh Theme

Themes and I was wondering how can I make my ➜ start in a new line instead its between the $USER %M and pwd:
`function get_pwd() {
echo "${PWD/$HOME/~}"
}
local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ %s)
"PROMPT='%{$fg[white]%}$USER%{$fg[cyan]%}%M ${ret_status}%{$fg_bold[green]%}%p %{$fg[yellow]%}$(get_pwd)%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'
ZSH_THEME_GIT_PROMPT_PREFIX="❮ %{$fg[red]%}"
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[blue]%}❯ %{$fg[yellow]%}%{$reset_color%}"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg[blue]%}❯"
`
Okay I think I figured it out but I am not sure if its the proper way to do it any suggestions are welcome so basically I put the local ret_status="%(?:%{$fg_bold[green]%}➜ :%{$fg_bold[red]%}➜ %s)
"PROMPT='%{$fg[white]%}$USER%{$fg[cyan]%}%M %{$fg[yellow]%}$(get_pwd)%{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}
${ret_status}%{$fg_bold[green]%}%p % %{$reset_color%}'
You can find your answer in this post about ZSH NEWLINE options.

Alias in bash to add formatted current date to git commit message

I am trying to add alias for a default commit message, something like this:
alias gc='git commit -m "Default commit: $(date)"'
but I don't like date's default format and would like to change it to this:
date +'%A, %d %B %Y %H:%M:%S' # Tuesday, 02 May 2017 23:12:07
I run into problem of how to build this in alias. I cannot handle the multiple double and single quotes. Can someone help?
Edit.
Thanks for the suggestion on using function and the code. Based on that I have made this, slightly changed:
gc ()
{
if [ "$#" == "0" ]; then
itsmsg="Deafult commit";
else
itsmsg="$*";
fi;
git commit -m "$itsmsg ($(date +'%A, %d %B %Y %H:%M:%S'))"
}
As #123 mentioned, you should use a function instead of an alias. This eliminates a level of quoting.
gc () {
git commit -m "Default commit: $(date +'%A, %d %B %Y %H:%M:%S')" "$#"
}
Use ANSI C quoting so that you can escape single quotes inside single quotes:
alias gc=$'git commit -m "Default commit: $(date +\'%A, %d %B %Y %H:%M:%S\')"'

How do I elegantly print the %z (timezone) format in Perl on Windows?

An offshoot of How do I elegantly print the date in RFC822 format in Perl?, but Windows specific.
On windows:
C:\> perl -MPOSIX
print strftime('%z', localtime()),"\n";
Yields:
Central Daylight Time
I was expecting:
-0500
As anyone would on a Linux system. How can I get the "-0500" on Windows?
UPDATE:
Is this really terrible to do in its place? (Assuming I'm not allowed to install DateTime or package it in any way)
C:\> perl -MPOSIX
sub tzoffset {
my $t = time();
my $utc = mktime(gmtime($t));
my $local = mktime(localtime($t));
return ($local - $utc);
}
sub zformat {
my ($tzoffset) = #_;
my $z = '';
if ($tzoffset < 0) {
$z .= '-';
$tzoffset *= -1;
}
my $hours = floor($tzoffset / 60 / 60);
my $minutes = $tzoffset - $hours * 60 * 60;
$z .= sprintf('%02d%02d', $hours, $minutes);
return $z;
}
print zformat(tzoffset()),"\n";
The problem I've noticed is that this returns -0600 vs -0500 (which I'd expect), but my guess is that is due to DST calculations or something? I'm mainly looking for a decent approximation, but I can't figure out why mktime() is playing with DST?
UPDATE:
Found out that tzoffset() can be much more "stable" in terms of DST if you just manually force DST off.
sub tzoffset {
my $t = time();
my $utc = mktime(gmtime($t));
my #tmlocal = localtime($t);
$tmlocal[8] = 0; # force dst off, timezone specific
my $local = mktime(#tmlocal);
return ($local - $utc);
}
This way, no matter if you're DST or not, it'll always return -0500 which is what you want from %z.
I think the reason you're getting the former is because
%z is Linux specific
On Windows it's somehow going all case-insensitive on you and picking up upper-case Z instead.
From manpage:
%Z Time zone name or abbreviation, or no bytes if no time
zone information exists.
Also, "%z" seems to be Linux specific - does not work on Solaris either:
$ perl -MPOSIX -e 'print strftime("%z", localtime()),"\n"'
%z
$ perl -MPOSIX -e 'print strftime("%Z", localtime()),"\n"'
EDT
whereas on Linux I get:
$ perl -MPOSIX -e 'print strftime("%z", localtime()),"\n"'
-0400
If you have DateTime::Format installed, I think it might suport %z based on POD. I don't have it installed so can't test yet
Also DateTime may support it without the DateTime::Format.

Resources