Formatting timestamp in bash for use in a file operation - bash

I'm getting some strangeness from bash when I try to use a timestamp as part of a filename.
#!/bin/bash
DATE=`date -d "today" +"%Y%m%d-%H:%M"`
dtl=$DATE.log
for drive in $( ls /dev/disk/by-id | grep 'scsi-35' ); do
mkdir -p /home/tt/drivelog/${drive}
cp /home/tt/drivelog/currentset/$drive.log "/home/tt/drivelog/$drive/$dtl"
done
The above results in a file named 20171122-12/15.log, so my comma has turned into a forward slash = not what I want.
I tried (to no avail) escaping out the colon by using:
DATE=date -d "today" +"%Y%m%d-%H\:%M"
which results in a file named 20171122-12\/15.log
I use double quotes to ensure there was no ambiguity in the reference, which can happen with colons in filenames. Didn't fix.
When I try some debugging and just echo the source and destination portions of the cp command, it looks right. But that normality disappears when I join them together in the cp command. Echo output:
/home/tt/drivelog/currentset/scsi-35000c50094vv123z.log
/home/tt/drivelog/scsi-35000c50094vv123z/20171122-11:55.log
Lastly, substituting .../${drive}/${dtl}" doesn't fix it...
Many thanks! (Image below, showing recent results)
for John1024:
I made sure date was working, output from date cmd:
20171122-12:47
and as reported in bash:
+ dtl=20171122-12:50.log
Using bash to run the script highlighted the issue:
1. The command is working properly...
+ cp /home/tt/drivelog/currentset/scsi-35000c50094aa123z.log /home/tt/drivelog/scsi-35000c50094aa123z/20171122-12:50.log
The issue is that the Mac on which I am looking at the folder is not showing the output properly.
ls in the output directory shows:
20171122-11:58.log
20171122-12\:00.log
20171122-12\:27.log
20171122-12\:48.log
20171122-12:50.log
Yet the view of this from my Mac drops the colon
I'm going to mark this as closed, as the underlying issue is a Mac AFP display incongruity issue, and not a bash issue. See: here Mac OS used colons as path separators when I first started using them in 1984. With the move to OS X, now eons ago, that changed. AFP and third-party implementations of AFP come with "YMMV" caveats, and this is apparently one I missed.
Many thanks to John1024

The issue here is that the underlying colon is not showing properly over AFP.
The code above does, actually, generate colons as intended. See here for more on the idiosyncrasies of OS X (and prior versions).

Related

Cygwin on Windows 7 (64bit): No such file or directory - but 'which' does give me the correct path

A formely working bash script no longer works after switching computers. I get the following error:
No such file or directory.
Before going on, please excuse any mistakes you may find since english is not my native language.
The script was used in cygwin under Windows XP. I now had to switch to cygwin64 under Windwos 7 (64bit).
The script is used as a checkhandler for the program SMSTools3 to split a file with a specific format into multiple smaller ones, which the program then uses to send SMS to multiple recipients. The script was copied directly from the page of SMSTools3 and uses the package formail.
After looking up the error the most likely problem was that the environmantle path was not set up to look in the right path (/usr/bin). I therefore added it to the path but to no avail.
I then deleted other entries in the enviromental path of windows which contained spaces because that could have been another explanation, but again to no avail.
Following is a minimal example of the code which produces the error.
#!/bin/bash
# Sample script to allow multiple recipients in one message file.
# Define this script as a checkhandler.
echo $PATH
which formail
outgoing="/var/spool/sms/outgoing"
recipients=`formail -zx "To:" < "$1"`
I added the lines the lines echo $Path and which formail to show if the script can find the correct file. Both results look fine, the second command gives me the right output '/usr/bin/formail'
But the line recipients=... throws me the error:
No such file or directory.
I do not have much experience with bash scripting, or cygwin in general. So if someone on this wonderful board could help me solve this problem, I would be really grateful. Thank you all for your help.
EDIT:
First of all thank you all for your comments.
Secondly, I would like to apologize for the late reply. The computer in question is also used for other purposes and my problem is part of a background routine, so I have to wait for "free time" on the pc to test things.
For the things #shellter pruposed: The ls command returned an error: '': No such file or directory.
The which -a formail as well as the echo $(which -a formail) commands that #DougHenderson pruposed returned the 'right' path of /usr/bin/formail. echo \$1 = $1 before the recipent line returned the path to the checkhandler file (/usr/local/bin/smsd_checkhandler.sh), the same command after the recipent line seems to show a empty string ($1 = ). Also, the pruposed change to the recipent line did not change the error.
For the dos2unix conversion that #DennisWilliamson pruposed, I opened the file in notepad++ to use their build in converion, but it showed me that the file is in unix format with Unix style line endings.

How can I remove the last n characters of filenames in a certain directory (in Mac terminal)- unix?

I am trying to rename using "mv", because "rename" command doesn't work in my Mac terminal.
I have a bunch of files named
DTM001_ACGGT-TTAGGC.fq
DTM156_GGTTG-ACAGTG.fq
...etc
I wish to rename them to
DTM001.fq
DTM156.fq
I suppose the easier way is to remove the last 13 characters before the file extension?
I tried these links:
mac os x terminal batch rename
Rename file by removing last n characters
Removing last n characters from Unix Filename before the extension
but none have worked for me, perhaps because I do not fully understand how to manipulate the answers for my specific case or some answers use "rename" command which I cannot access.
The macOS Terminal is simply an interface to an interactive program called a shell. The default shell's name is bash.
What you are looking for is known as a shell script, or a bash script, to rename files.
The questions you referenced have the answer. To reiterate:
cd directory_with_the_files
for file in *.fq; do
mv -vn "${file}" "${file%_*}.fq"
done
You can type this all in at the command line, or place it into a file and execute it with:
bash file_containing_the_commands
This will go through all .fq files in the current directory, renaming them to what you want. The -v option to mv simply means to print the rename as it happens (useful to know that it's doing something), and the -n flag means don't accidentally overwrite any files (in case you type something in wrong or come across duplicate numbers).
All the magic is happening in the ${file%_*}.fq, which says
"remove everything after the first _ and add the .fq back". This is known as a "shell parameter expansion," which you can read more about in the Bash Reference Manual. It's somewhat obtusely worded, but here is the relevant bit to this particular use case:
${parameter%word}
The word is expanded to produce a
pattern just as in filename expansion. If the pattern matches a
trailing portion of the expanded value of parameter, then the result
of the expansion is the value of parameter with the shortest matching
pattern (the '%' case) deleted.
The simplest way is to use rename - see instructions at the end for installation on a Mac.
So, in answer to your question, you can see what would happen if you replace (the command is actually s for "substitute") everything from the first underscore to the end of the filename with .fq:
rename --dry-run 's/_.*/.fq/' *fq
'DTM001_ACGGT-TTAGGC.fq' would be renamed to 'DTM001.fq'
'DTM156_GGTTG-ACAGTG.fq' would be renamed to 'DTM156.fq'
If that looks good, remove the --dry-run and run it again for real.
You can use rename on your Mac, if you install it. By default, Apple doesn't ship a package manager with macOS. So, many folk use homebrew from the homebrew website.
If you have that, you can simply install rename with:
brew install rename
Then, you'll have a package manager and you can benefit for all sorts of lovely software including new, up-to-date versions of all the out-of-date, ancient versions of your favourite tools that Apple ships:
PHP
Perl
ImageMagick
GNU sed
GNU awk
GNU find
GNU Parallel
zeromq
htop
socat
sox
ffmpeg
youtube-dl
zenity
redis
feh
mosquitto
doxygen
pandoc etc.

date no such file or directory

I'm trying to script something that isn't outputting quite correctly with the date command. Here's the contents of what I have thus far:
#!/bin/bash
# Get RPM manifest
# Output written to /tmp
NOW=$(date +%D)
rpm -qa --qf="%{NAME}.%{ARCH}\n" | sort > /tmp/$HOSTNAME.RPM_Manifest.$NOW.txt
When I run this script, I get this message:
[root#linmachine1 ~]# sh /usr/local/bin/rpm_manifest.sh
/usr/local/bin/rpm_manifest.sh: line 7: /tmp/linmachine1.RPM_Manifest.03/01/17.txt: No such file or directory
I suspect the problem is in how the date formatting within the NOW variable I'm defining may be the culprit. I've tried with and without quotes and get the same thing. Looking at the man pages, I didn't see a way to change the default behavior such that the forward slashes would be replaced by dots, as I believe this is where the problem lies.
EDIT: Thanks for all of your responses. I'm not real sure why this was downvoted though. I asked a legitimate question. What gives?
Yes, you shouldn't have slashes in a file name.
Use:
now=$(date "+%d.%m.%Y")
rpm -qa --qf="%{NAME}.%{ARCH}\n" | sort > "/tmp/$HOSTNAME.RPM_Manifest.$now.txt"
instead, or replace the . with whatever you prefer

Setting the current date into a variable in a Script in bash

So for the life of me I cannot figure out why my script will not take my date command as a variable. I have a script that is run every time a message is received and procmail filters specific messages by their subject line. The script looks like this:
d=$(date +%Y%m%d)
:0 wc
* ^(From|subject).*xxx
| cat&>/xx/xx/xx/xx/MSG:$d && \
chmod xxx /xx/xx/xx/xx/MSG:$d && \
/xx/xx/xx/otherscript.sh /xx/xx/xx/xx/MSG:$d
I have run the date command plenty of times in other scripts and to stdout without any issue, so I am wondering if this is a procmail issue? I have looked at a few different sites about this but still have not found a solution. My end goal is to create unique file names as well as for organization purposes each time a new email comes in.
The other reason for me believing it has something to do with procmail is that it was working fine just 3 months ago (didn't change any files or permissions). I have even tried several variations (only showing a few examples):
$'date +"%Y%m%d"'
$(date)
echo $(date)
I get a variety of files created ranging with it printing MSG:(date), MSG:(date ,etc. MSG:(date appears to like it tries to read the variable but is getting cut off or the space between date and + is causing an issue.
And at the end of my script I send it to another script which also creates a new file with the date appended and it works just fine:
fileOut="/xxx/xxx/xxx/xxx.$v.$(date +"%Y%m%d-%H%M%S").xxx"
prints: xxx.YH8AcFV9.20160628-090506.txt
Thanks for your time :-)
Procmail does not support the modern POSIX shell command substitution syntax; you need to use backticks.
d=`date +%Y%m%d` # or just date +%F
If you want to avoid invoking an external process, the From_ pseudo-header contains a fresh date stamp on many architectures.

Simple shell script doesn't work like command line?

I'm trying to write a script that contains this
screen -S demo -d -m which should start a new screen session named demo and detach it.
Putting screen -S demo -d -m in the command line works.
If I put it in a file named boot.sh, and run it ./boot.sh I get
Error: Unknown option m
Why does this work in the command line but not as a shell script?
This file was transferred from windows and had ctrl-M characters.
Running "screen" on my Linux machine, a bad option (Screen version 4.00.03jw4 (FAU) 2-May-06) gives the error,
Error: Unknown option -z"
while your description includes no dash before the offending option. I'd check that the characters in your script file are what you expect them to be. There are many characters that look like a dash but which are not.
cat -v boot.sh
may show something interesting as it'll show codes for non-ascii characters.
This may seem a little like the "make sure your printer is plugged in" kind of help, but anyway:
have you tried to check if the screen you're invoking from the script is the same as the one invoked from the command line ?
I'm thinking you may change the PATH variable inside your script somewhere and perhaps screen from the script would be something else (a different version, perhaps ?).

Resources