How can I rename a file with Ruby that includes a / character? - ruby

I've written a little Ruby command line app that I use to keep TV Shows organized on my Mac harddrive. Given the nature of TV episode titles there are episodes which include the / character.
Being on a Mac, the filesystem actually allows me writing this file and if I manually rename the file with the / character in it everything is fine.
The moment Ruby's File.rename runs in my script however I simply get a No such file or directory error because Ruby tries to read the / in the filename as a folder which should exist.
Here is an example:
Output path is /TV/Showname/Season 1/Showname - 1x07 - 5/1.mp4
Now rather than looking for the folder /Showname - 1x07 - 5/ and write to a 1.mp4 file inside of it, how can I tell ruby to simply take the filename (Showname - 1x07 - 5/1.mp4) and write it into the Season 1 folder as is?
Thanks for reading.

A weird one this, but because the backslash is used as a file-separator, it is converted to a colon in the filename used by Ruby. So to rename your file, replace the forward slash in the name with a colon.
So you would write something like:
File.rename("Showname - 1x07 - 5:1.mp4", "/TV/Showname/Season 1/Showname - 1x07 - 5:1.mp4")

Related

Move files based on filename using command prompt

I am trying to move files from a location to another one based on filename ONLY by using command line. The below works pretty fine but I do not want to specify both, the file name and the extension:
MOVE C:\firstlocation\file.sdltm "C:\secondlocation\file.sdltm"
The reason behind this is that I have the following files in the firstlocation:
file.sdltm
file.tmx
and my aim is to move both files named "file" to the secondlocation regardless the extension.
Sorry if this question has been asked before, - couldn't find any that matches my criteria.

Command prompt batch renaming results in syntax error

I need to rename 80k files in multiple folders & subfolders in the same directory. I have been trying to use ren but have been unsuccessful; I get an incorrect syntax error.
My old name looks like this:
c:/users/alice/BiDIR_DOCS_2017_Nov08020423\Company,LLC##NA##7967425.00##7967425.00\Company LLC A and A - Aug2017.pdf BiDIR_DOCS_2017_Nov08020423\Company, LLC##NA##7967425.00##7967425.00\document_# (x.y.z)-test~.pdf
and my new name looks like this:
c:/users/alice/BiDIR_DOCS_2017_Nov08020423\Company,LLC##NA##7967425.00##7967425.00\Company LLC A and A - Aug2017.pdf BiDIR_DOCS_2017_Nov08020423\Company, LLC##NA##7967425.00##7967425.00\system, a old name~ ` to # system b document (xyz)-test.pdf
I have the existing directory print in one column of Excel and in the next column what I want the directory print to be.
I'm not sure if I'm starting my ren command at the right hierarchy of my directory, or if I need quotation marks to keep the spaces and symbols in my new name.
I have tried improvising and testing on my own without success and I cannot find an article online on point.
Try FAR (find and replace) - it a free utility that works well.
http://findandreplace.sourceforge.net/

sql loader without .dat extension

Oracle's sqlldr defaults to a .dat extension. That I want to override. I don't like to rename the file. When googled get to know few answers to use . like data='fileName.' which is not working. Share your ideas, please.
Error message is fileName.dat is not found.
Sqlloder has default extension for all input files data,log,control...
data= .dat
log= .log
control = .ctl
bad =.bad
PARFILE = .par
But you have to pass filename without apostrophe and dot
sqlloder pass/user#db control=control data=data
sqloader will add extension. control.ctl data.dat
Nevertheless i do not understand why you do not want to specify extension?
You can't, at least in Unix/Linux environments. In Windows you can use the trailing period trick, specifying either INFILE 'filename.' in the control file or DATA=filename. on the command line. WIndows file name handling allows that; you can for instance do DIR filename. at a command prompt and it will list the file with no extension (as will DIR filename). But you can't do that with *nix, from a shell prompt or anywhere else.
You said you don't want to copy or rename the file. Temporarily renaming it might be the simplest solution, but as you may have a reason not to do that even briefly you could instead create a hard or soft link to the file which does have an extension, and use that link as the target instead. You could wrap that in a shell script that takes the file name argument:
# set variable from correct positional parameter; if you pass in the control
# file name or other options, this might not be $1 so adjust as needed
# if the tmeproary file won't be int he same directory, need to be full path
filename=$1
# optionally check file exists, is readable, etc. but overkill for demo
# can also check temporary file does not already exist - stop or remove
# create soft link somewhere it won't impact any other processes
ln -s ${filename} /tmp/${filename##*/}.dat
# run SQL*Loader with soft link as target
sqlldr user/password#db control=file.ctl data=/tmp/${filename##*/}.dat
# clean up
rm -f /tmp/${filename##*/}.dat
You can then call that as:
./scriptfile.sh /path/to/filename
If you can create the link in the same directory then you only need to pass the file, but if it's somewhere else - which may be necessary depending on why renaming isn't an option, and desirable either way - then you need to pass the full path of the data file so the link works. (If the temporary file will be int he same filesystem you could use a hard link, and you wouldn't have to pass the full path then either, but it's still cleaner to do so).
As you haven't shown your current command line options you may have to adjust that to take into account anything else you currently specify there rather than in the control file, particularly which positional argument is actually the data file path.
I have the same issue. I get a monthly download of reference data used in medical application and the 485 downloaded files don't have file extensions (#2gb). Unless I can load without file extensions I have to copy the files with .dat and load from there.

Rename subfolder: add leading word from parent folder

I have a large music library organized in Artist folders with Album subfolders:
Artist 1
- Album A
-- File 1
-- File 2
- Album B
-- File 1
-- File 2
Artist 2
- Album C
-- File 1
-- File 2
- Album D
-- File 1
-- File 2
Now I want to rename all Album folders by adding the Artist name as prefix AND move all Album folders in to the root directory, like this:
Artist 1 - Album A
- File 1
- File 2
Artist 1 - Album B
- File 1
- File 2
Artist 2 - Album C
- File 1
- File 2
Artist 2 - Album D
- File 1
- File 2
What is the best way to do that? I tried to do it with Total Commander, but I don't get it. Or maybe shell, mp3tag? I use Windows 10.
Thanks!
This could be done in several ways, actually. I'll show how in bash, but that's only if you have that thing of Bash on Ubuntu on Windows. Again:
BASH
Assuming that your music library is ~/Music/, that all the artist folders are inside, that you accept to have everything moved to a new folder, assuming that it doesn't yet exist (because if you had an artist folder named 'CoolSinger' and just accidentally you also have another artist folder named 'CoolSinger - CoolAlbum', by a mistake, there would be problems...), and that there are not any other files involved than what you state, the shell script would look like this:
#!/bin/bash
mkdir ~/NewMusic/
for artistdir in ~/Music/*; do
artistname="$(basename "${artistdir}")"
for albumdir in "${artistdir}"/*; do
albumname="$(basename "${albumdir}")"
mv "${albumdir}" ~/NewMusic/"${artistname} - ${albumname}" 2>/dev/null
done
done
And let me explain it in human:
Create the destination folder. Then, for every artist (assuming all are folders); iterate through every album sub-folder, moving it to the new folder, and renaming it, by the way, using the artist name and folder name from the actual folder names. If everything went OK, this would result in:
A folder ~/Music/ with the original sub-folder names, but they're now empty.
A folder ~/NewMusic with the desired structure.
If an artist folder is empty, the shell would try to throw an error because it expands to the literal string (explained later), but don't worry, because if it is empty, then anything is to do with it, so you can ignore it, appending 2>/dev/null to the command. However, if anything else goes wrong with this, it will also be silenced.
If you wanted to, let's say, stay with the original files, and have a copy of all that with the desired structure, you should change the mv command for a cp -R one.
And all that is for a script, in a file. If you wanted to execute it right from the command line, which would make somewhat tricky to change the folder name for the music library, it would look like this:
mkdir ~/NewMusic/; for artistdir in ~/Music/*; do artistname="$(basename "${artistdir}")"; for albumdir in "${artistdir}"/*; do albumname="$(basename "${albumdir}")"; mv "${albumdir}" ~/NewMusic/"${artistname} - ${albumname}"; done; done
And an explanation of everything there:
mkdir creates the directory.
for A in B ; do C ; done is a loop. It loops through every string separated by one of the IFS characters in B, and assign it as a value for the variable A, while it executes C.
Note that the text in the script has an asterisk. The shell expands a string with an asterisk to what it finds to match the pattern. For instance, if you had a bunch of Word documents, typing echo *.docx would expand to every name matching that ending, in the current folder (in another case, echo /path/*.docx).
So, for every folder inside the specified directory, assign (once for every artist folder) the variable artistname with the base name of the file specified (in this case, the folder) as its value. So, basename /path/to/anything returns anything.
With the help of another for loop, do for every element inside the artist directory, rename it as specified, and if the new name is in another directory, it will move it there.
Again, the 2>/dev/null redirection is there to redirect all output in stderr to the void. Output in stdout would be still printed, though, if there was any.
SOME IMPORTANT NOTES
I don't have any idea whether the shell from Bash on Ubuntu on Windows detects /dev/null as the special character file that a standard UNIX machine has or not. Likely it does, or it wouldn't be compatible with so many things.
This is only if you have Bash on Ubuntu on Windows in your Windows 10. If I recall correctly, the chance of using it was implemented with the Anniversary Update. If you have the update, but not bash, I recommend you to install it. There are several guides over that on the Internet.
About the folder structure. I suspect the same about /dev/null as for the POSIX folder structure: that it follows it, as it's not just Bash on Windows, but Bash on Ubuntu on Windows.
I found an answer by myself. The best way to do it is to use mp3tag tool. You can create new folders and copy your files in it.
Select Converter > Tag - Filename
Type in:
E:\%artist% - %album%\$num(%track%,2) - %title%
You'll receive a directory with Artist - Albumname\01 - File.mp3

Renaming files of variable length in DOS

I'm trying to rename files that have '#' to '_'.
I understand that there is a straigt forward way of replacing the nth character in a file.
How do we rename files , if # symbol is present in different places in different files
For example, assuming the below files are present in a directory
a#file.txt
asdf#kfi.png
uiuydfjfk#kdi.txt
I want the output to be like this one
a_file.txt
asdf_kfi.png
uiuydfjfk_kdi.txt
Is there anyway to accomplish this ?
This uses a helper batch file called repl.bat from - http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
It creates renfile.bat for you to examine for errors, and then execute.
dir *#* /b |repl "(.*)(#)(.*)" "ren \x22$&\x22 \x22$1_$3\x22" x >renfile.bat

Resources