I want to rename folders from lowercase to uppercase. For example
abc ABC
twoshirts TwoShirts
I've tried
mv -T -f source destination
I've tried a few different combination but I get an error
Error moving files as they are the same file or sub directory of itself.
Is it possible to do it with mv?
The problem is that your file system is case-insensitive; UNIX and its derivatives like Linux have traditionally had case-sensitive filesystems, but Windows doesn't. So you have to first rename the file to some other name, and then from there to the target name.
e.g. mv abc notabc; mv notabc ABC
Related
I need to rename files in multiple directories to the name of the parent directory and move them up one directory and the delete the empty directories.
Sample structure:
/export
exp_20210101
3747-46473-328383-5555
exp_20210102
4533-45323-354345-5366
Desired result:
/export
exp_20210101
exp_20210102
3747-46473-328383-5555 renamed to exp_20210101
No extensions (Linux)
I prefere to do it with a bash script.
Already tried several samples (similar questions), but they're not working for my case.
I need to rename files in multiple directories to the name of the parent directory and move them up one directory and the delete the empty directories.
I don't think that's possible, you can't have a regular file and a directory with the same name in the same directory.
You should move each file to the same level as its parent without changing its name instead (assuming a file with the same name may not exist there). Then you can remove the parent and rename the file to its name.
for f in /export/*/*; do
echo mv "$f" "${f%/*/*}"
echo rmdir "${f%/*}"
echo mv "${f%/*/*}/${f##*/}" "${f%/*}"
done
Drop echos if the output looks good.
I am new to Bash.
I would like to write a script which has three variables:
The old file name
The new file name
The name of a directory to move the file to
I'm trying to change the name of the file and move it into the directory.
I know that using mv can change the name and to move it to other directory.
I know how to do it using commands that I just type in the terminal but I have some trouble to use variables in those commands. The directory is located in the same location as the file and I run the script from there.
Example:
old_file="abc"
new_file="cba"
dir="yyy"
Result: No more file called abc in ., but there is a file called cba in ./yyy witch contains the same information that abc had.
Basically you need to invoke the mv command using the script variables. Notice that the variables are between double quotes to avoid bash splitting the names when finding spaces or other special characters.
#!/bin/bash
old_file=$1
new_file=$2
dir=$3
mv "$old_file" "$dir"/"$new_file"
And you should invoke it as:
./script "abc" "cba" "yyy"
Finally, notice that the file "abc" must exist in the current directory (the one where the script is), and the folder "yyy" must also exist in the current directory (or be an absolute path).
I have a lot of files named the same, with a directory structure (simplified) like this:
../foo1/bar1/dir/file_1.ps
../foo1/bar2/dir/file_1.ps
../foo2/bar1/dir/file_1.ps
.... and many more
As it is extremely inefficient to view all of those ps files by going to the
respective directory, I'd like to copy all of them into another directory, but include
the name of the first two directories (which are those relevant to my purpose) in the
file name.
I have previously tried like this, but I cannot get which file is from where, as they
are all named consecutively:
#!/bin/bash -xv
cp -v --backup=numbered {} */*/dir/file* ../plots/;
Where ../plots is the folder where I copy them. However, they are now of the form file.ps.~x~ (x is a number) so I get rid of the ".ps.~*~" and leave only the ps extension with:
rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;
Then, as the ps files have hundreds of points sometimes and take a long time to open, I just transform them into jpg.
for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;
This is not really a working bash script as I have to change the directory manually.
I guess the best way to do it is to copy the files form the beginning with the names
of the first two directories incorporated in the copied filename.
How can I do this last thing?
If you just have two levels of directories, you can use
for file in */*/*.ps
do
ln "$file" "${file//\//_}"
done
This goes over each ps file, and hard links them to the current directory with the /s replaced by _. Use cp instead of ln if you intend to edit the files but don't want to update the originals.
For arbitrary directory levels, you can use the bash specific
shopt -s globstar
for file in **/*.ps
do
ln "$file" "${file//\//_}"
done
But are you sure you need to copy them all to one directory? You might be able to open them all with yourreader */*/*.ps, which depending on your reader may let browse through them one by one while still seeing the full path.
You should run a find command and print the names first like
find . -name "file_1.ps" -print
Then iterate over each of them and do a string replacement of / to '-' or any other character like
${filename/\//-}
The general syntax is ${string/substring/replacement}. Then you can copy it to the required directory. The complete script can be written as follows. Haven't tested it (not on linux at the moment), so you might need to tweak the code if you get any syntax error ;)
for filename in `find . -name "file_1.ps" -print`
do
newFileName=${filename/\//-}
cp $filename YourNewDirectory/$newFileName
done
You will need to place the script in the same root directory or change the find command to look for the particular directory if you are placing the above script in some other directory.
References
string manipulation in bash
find man page
Im trying to display a text file in a directory within the folder my script is in. I tried things like:
mypath=`realpath $0`
FILE="$realpath/Folder/Text.txt"
cat $FILE
And
FILE="$PWD/Folder/Text.txt"
cat $FILE
but they include the name of the file instead of just the its running from. I also want it to work with symbolic links.
cat "$(dirname -- "$0")/Folder/Text.txt"
That is, send the file Text.txt in the directory Folder below the directory where this script is located to standard output.
This will work with symlinks. And yes, all the quotes are significant.
You can do:
cat "./Folder/Text.txt"
the period denotes the current folder you are in. a double period "../Folder/Text.txt" denotes a folder up in the directory tree.
I'm trying to copy all files of ".sh" saved in one directory to another.
I can copy the entire directory using
cp -rp ~/Documents/ToCopy ~/Documents/CopyToHere
but I cannot figure out how to select only the .sh files
Is there also anyway to change the file names of the copied files?
cp -rp ~/Documents/ToCopy/*.sh ~/Documents/CopyToHere
The * is a wildcard character that represents any number of characters in the filenames, so *.sh matches any file in that directory that ends in sh.
I'm pretty sure the wildcard character (*) is parsed by the shell itself, not by the cp command (so watch out if you are calling it from somewhere that isn't a shell).
You can try typing
cp -rp ~/Documents/*.sh ~/Documents/CopyToHere
The *.sh selects all files in the directory whose names end in ".sh" using regular expressions. As another example, you could copy all files whose names contain the word "pizza" by typing *pizza* on the command line.
Did you try doing *.sh so that you have cp ~/Documents/*.sh ~/Documents/CopyToHere ? That should work...