Move file with a dash - command-line

I move file using Midnight Commander to file with name "-name.csv". But 'mc' thinks I use option. Why is this happening? And how I can move to file with name like "-name.csv".
desktop:~/s$ mv name.csv "-name.csv"
mv: invalid option -- 'a'

It's not mc, it's mv. Quoting doesn't help because the quotes are interpreted by the shell so mv receives unquoted parameters name.csv and -name.csv. You need to hide the dash so that option parser in mv stops thinking it's an option. Use relative path ./ for the current directory, or full path:
mv name.csv ./-name.csv
mv name.csv "`pwd`"/-name.csv

Related

How to pass a variable to the mv command to rename a file text with spaces and the variable's text in a bash (.sh) file

I create a variable and store the day, date & time in it:
NOW=$(date "+%a %d/%m/%Y% %H:%M")
Then I would like to pass $NOW to the mv command to rename a file.
e.g. Create file named a.txt with a title and the current date:
printf "File Report (" > ~/Desktop/a.txt
echo $NOW"):\n" >> ~/Desktop/a.txt
Then I try to rename the file with the variable ($NOW) included in the name:
mv ~/Desktop/a.txt ~/Desktop/'File Report $NOW'.txt
What should that last line be? I also tried these two options.
mv ~/Desktop/a.txt ~/Desktop/'File Report' $NOW.txt
&
mv ~/Desktop/a.txt ~/Desktop/'File Report'${NOW}.txt
Assuming a reasonably Bourne-like shell (such as bash), variable substitution does not happen inside single quotes. You need to use double quotes:
mv ~/Desktop/a.txt "${HOME}/Desktop/File Report ${NOW}.txt"
(I'm not sure whether the curly braces are required, but they can't hurt)
You will also need to change the date command to avoid the use of slashes. For example:
NOW="$(date '+%a %d-%m-%Y% %H:%M')"

I can't make the mv command work on a Mac terminal

I am trying to move a file from Downloads to a folder on my desktop.
I keep getting this:
Why does the usage message appear afterwards?
It looks like your file has a space in it, so it needs to be escaped. Otherwise, mv tries to find a file named "Tres", one named "Beijos_C.pdf" and move them into that directory.
# Either...
mv Tres\ Beijos_C.pdf ~/Desktop/choro/
# ...or...
mv "Tres Beijos_C.pdf" ~/Desktop/choro/
If your file name contains spaces, you should surround it with " like this:
mv "my file name.txt" /home/user/Desktop

Running a script in bash

I have a script in one of my application folders.Usually I just cd into that locatin in Unix box and run the script e.g.
UNIX> cd My\Folder\
My\Folder> MyScript
This prints the required result.
I am not sure how do I do this in Bash script.I have done the following
#!/bin/bash
mydir=My\Folder\
cd $mydir
echo $(pwd)
This basically puts me in the right folder to run the required script . But I am not sure how to run the script in the code?
If you can call MyScript (as opposed to ./MyScript), obviously the current directory (".") is part of your PATH. (Which, by the way, isn't a good idea.)
That means you can call MyScript in your script just like that:
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
As I said, ./MyScript would be better (not as ambiguous). See Michael Wild's comment about directory separators.
Generally speaking, Bash considers everything that does not resolve to a builtin keyword (like if, while, do etc.) as a call to an executable or script (*) located somewhere in your PATH. It will check each directory in the PATH, in turn, for a so-named executable / script, and execute the first one it finds (which might or might not be the MyScript you are intending to run). That's why specifying that you mean the very MyScript in this directory (./) is the better choice.
(*): Unless, of course, there is a function of that name defined.
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
I would rather put the name in quotes. This makes it easier to read and save against mistakes.
#!/bin/bash
mydir="My Folder"
cd "$mydir"
echo $(pwd)
./MyScript
Your nickname says it all ;-)
When a command is entered at the prompt that doesn't contain a /, Bash first checks whether it is a alias or a function. Then it checks whether it is a built-in command, and only then it starts searching on the PATH. This is a shell variable that contains a list of directories to search for commands. It appears that in your case . (i.e. the current directory) is in the PATH, which is generally considered to be a pretty bad idea.
If the command contains a /, no look-up in the PATH is performed. Instead an exact match is required. If starting with a / it is an absolute path, and the file must exist. Otherwise it is a relative path, and the file must exist relative to the current working directory.
So, you have two acceptable options:
Put your script in some directory that is on your PATH. Alternatively, add the directory containing the script to the PATH variable.
Use an absolute or relative path to invoke your script.

Is it possible to execute a command relative to a Terminal shell script?

I have a Terminal shell script file start.command that I launch from finder with:
ls -l
The file is in ~/foo but list ~, can I get the path of it's containing dir. I'd like to launch an application that is in the same folder as the file when the user runs the .command but it seems like I would need the absolute path to the file for that to work.
Assuming bash, you need to cd to the script's enclosing directory before running ls.
You can one-line it with this:
cd "$(dirname "$0")"
$0 is the script's relative path, i.e. whatever you used on the command line to invoke it. dirname strips the filename from the path.
$() is a value expansion to feed to cd, and the quotes are all necessary to handle things like spaces in paths.

Change file extensions of multiple files in a directory with terminal/bash?

I'm developing a simple launchdaemon that copies files from one directory to another. I've gotten the files to transfer over fine.
I just want the files in the directory to be .mp3's instead of .dat's
Some of the files look like this:
6546785.8786.dat
3678685.9834.dat
4658679.4375.dat
I want them to look like this:
6546785.8786.mp3
3678685.9834.mp3
4658679.4375.mp3
This is what I have at the end of the bash script to rename the file extensions.
cd $mp3_dir
mv *.dat *.mp3
exit 0
Problem is the file comes out as *.mp3 instead of 6546785.8786.mp3
and when another 6546785.8786.dat file is imported to $mp3_dir, the *.mp3 is overwritten with the new .mp3
I need to rename just the .dat file extensions to .mp3 and keep the filename.
Ideas? Suggestions?
Try:
for file in *.dat; do mv "$file" "${file%dat}mp3"; done
Or, if your shell has it:
rename .dat .mp3 *.dat
Now, why your command didn't work: first of all, it is more than certain that you only had one file in your directory when it was renamed to *.mp3, otherwise mv would have failed with *.mp3: not a directory.
And mv does NOT do any magic with file globs, it is the shell which expands globs. Which means, if you had this file in the directory:
t.dat
and you typed:
mv *.dat *.mp3
the shell would have expanded *.dat to t.dat. However, as nothing would match *.mp3, the shell would have left it as is, meaning the fully expanded command is:
mv t.dat *.mp3
Which will create a file named, literally, *.mp3.
If, on the other hand, you had several files named *.dat, as in:
t1.dat t2.dat
the command would have expanded to:
mv t1.dat t2.dat *.mp3
But this will fail: if there are more than two arguments to mv, it expects the last argument (ie, *.mp3) to be a directory.
For anyone on a mac, this is quite easy if you have BREW, if you don't have brew then my advice is get it. then when installed just simply do this
$ brew install rename
then once rename is installed just type (in the directory where the files are)
$ rename -s dat mp3 *