mv: cannot overwrite directory with non-directory - linux

Is it possible to get around this problem?
I have a situation where I need to move some files to 1 directory below.
/a/b/c/d/e/f/g
problem is that the filename inside g/ directory is the same as the directory name
and I receive the following error:
mv: cannot overwrite directory `../297534' with non-directory
Example:
/home/user/data/doc/version/3766/297534 is a directory, inside there is a also a file named 297534
so I need to move this file to be inside /home/user/data/doc/version/3766
Command
This is what I am running: (in a for loop)
cd /home/user/data/doc/version/3766/297534
mv * ../

You can't force mv to overwrite a directory with a file with the same name. You'll need to remove that file before you use your mv command.

Add one more layer in your loop.
Replace mv * ../ with
for f in `ls`; do rm -rf ../$f; mv $f ..; done
This will ensure that any conflict will be deleted first, assuming that you don't care about the directory you're overwriting.
Note that this will blow up if you happen to have a file inside the current directory which matches the current directory's name. For example, if you're in /home/user/data/doc/version/3766/297534 and you're trying to move a directory called 297534 up. One workaround to this is to add a long suffix to every file, so there's little chance of a match
for f in `ls`; do mv $f ../${f}_abcdefg; done

Related

Remove directory structure, but keep directory contents

I meant to run this code inside a specific directory within my home directory, but accidentally ran it in my home directory itself:
i=0; for f in *; do d=dir_$(printf %03d $((i/8+1))); mkdir -p $d; mv "$f" $d; let i++; done
Now all my files and directories have been grouped into separate directories. I need to remove this action, and restore my original organization. Is this possible?
Using shell expansion:
mv dir_*/* .
should move the content of all dir_ subdirectories back into the current one. For "hidden" files, if necessary, move dir_*/.*.

Linux Bash: Move multiple different files into same directory

As a rather novice Linux user, I can't seem to find how to do this.
I am trying to move unique files all in one directory into another directory.
Example:
$ ls
vehicle car.txt bicycle.txt airplane.html train.docx (more files)
I want car.txt, bicycle.txt, airplane.html, and train.docx inside vehicle.
Right now I do this by moving the files individually:
$ mv car.txt vehicle
$ mv bicycle.txt vehicle
...
How can I do this in one line?
You can do
mv car.txt bicycle.txt vehicle/
(Note that the / above is unnecessary, I include it merely to ensure that vehicle is a directory.)
You can test this as follows:
cd #Move to home directory
mkdir temp #Make a temporary directory
touch a b c d #Make test (empty) files ('touch' also updates the modification date of an existing file to the current time)
ls #Verify everything is there
mv a b c d temp/ #Move files into temp
ls #See? They are gone.
ls temp/ #Oh, there they are!
rm -rf temp/ #DESTROY (Be very, very careful with this command)
Shorthand command to move all .txt file
You can try using a wildcard. In the code below, * will match all the files which have any name ending with .txt or .docx, and move them to the vehicle folder.
mv *.txt *.docx vehicle/
If you want to move specific files to a directory
mv car.txt bicycle.txt vehicle/
Edit: As mentioned in a comment, If you are moving files by hand, I suggest using mv -i ... which will warn you in case the destination file already exists, giving you a choice of not overwriting it. Other 'file destroyer' commands like cp & rm too have a -i option
mv command in linux allow us to move more than one file into another directory. All you have to do is write the name of each file you want to move, seperated by a space.
Following command will help you:
mv car.txt bicycle.txt airplane.html train.docx vehicle
or
mv car.txt bicycle.txt airplane.html train.docx vehicle/
both of them will work.
You can move multiple files to a specific directory by using mv command.
In your scenario it can be done by,
mv car.txt bicycle.txt airplane.html train.docx vehicle/
The point you must note is that the last entry is the destination and rest everything except mv is source.
One another scenario is that the destination is not present in our directory,then we must opt for absolute path in place of vehicles/.
Note: Absolute path always starts from / ,which means we are traversing from root directory.
I have written a small bash script that will move multiple files(matched using pattern) present in multiple directories(matched using pattern) to a single location using mv and find command in bash
#!/bin/bash
for i in $(find /path/info/*/*.fna -type f) # find files and return their path
do
mv -iv $i -t ~/path/to/destination/directory # move files
done
$() is for command substitution(in other words it expand the expression inside it)
/*/ wild card for matching any directory, you can replace this with any wild card expression
*.fna is for finding any file with.fna extension
-type f is for getting the full path info of the located file
-i in mv is for prompt before overwrite( extra caution in case the wild card exp was wrong)
-v for verbose
-t for destination
NOTE: the above flags are not mandatory
Hope this helps

Wrtie a script to Delete files if it exists in different folder in Linux

I'm trying write a script in linux. Where I have some csv files in Two different folders(A and B) and then after some processing copy of rejected files are moving to Bad Folder.
SO I want bad files to be deleted from Table A and B which have copied to Bad Folder.
Can you help me to write this script for linux?
Best
lets say name of Bad Folder is 'badFolder' and considering 'A', 'B' and 'badFolder' are in same directory
Steps to delete files from folder A and B:
step 1: change current directory to your 'badFolder'
cd badFolder
step 2: delete identical files
find . -type f -exec rm -f ../A/{} \;
find . -type f -exec rm -f ../B/{} \;
The argument -type f tells to look for files, not directories.
The -exec ... \; argument tells that, once it finds a file in 'badFolder', it should run the command rm -f on its counterpart in the A subdirectory.
Because rm is given with the -f option, it will silently ignore files that don't exist.
Also, it will not prompt before deleting files. This is very handy when deleting a large number of files. However, be sure that you really want to delete the files before running this script.
#!/bin/bash
#Set the working folder in which you want to delete the file
Working_folder=/<Folder>/<path>
cd $Working_folder
#command to delete all files present in folders
rm <filenames seperated by space>
echo "files are deleted"
#if you want to delete all files you can use wild card character
# e.g. command rm *.*
# if you want to delete a particular file say for deleting .csv file you can use command rm *.csv command
Set variables containing the paths of your A, B and BAD directories.
Then you can do something along the lines of
for file in ls ${PATH_TO_BAD}
do
rm ${PATH_TO_A}/$file
rm ${PATH_TO_B}/$file
done
This is iterating over the BAD directory and any file it finds, it deletes from the A and B directories.

How to create empty txt files in a directory reflecting files in another directory?

I need to do some testing and need the same file names as I have in directory /home/recordings in /home/testing folder.
For example, if i have a file recording01.mp4 in /home/recordings, i would want to have the an empty file recording01.txt or recording01.mp4 or in /home/testing
I understand I can use the following command?
for i in /home/recordings/*; do touch "$i"; done
Not sure how to specify extension or the destination directory in this case?
A simple addition of /home/testing/ to touch command will do it.
for i in /home/recordings/*; do
temp=`echo $i|cut -f3 -d'/'`
cd /home/testing/
touch "$temp";
cd ../..
done
I assume you are not in home directory and running this script file from anywhere else.
You can also do this without a loop
find /home/recordings/ -type f -printf /home/testing/%f'\n' | xargs -n1 touch
Try this:
for i in /home/recordings/*; do touch "/home/testing/$i"; done
You need only specify absolute paths and things will work fine. A bunch of 0-length files are created, their names corresponding to those in /home/recordings.

./mv.sh: line 4: cd: 1.4-1.5.csh: Not a directory

I want to move file1 to directory1 in many subdirectories of current directory. Both file1 and directory1 are in each subdirectory. I write the following script in current directory but it reports "./mv.sh: line 4: cd: directory1: No such file or directory". Actually, the directory1 is in each subdirectory.
1 #!/bin/bash
2
3 for i in *; do
4 builtin cd $i
5 mv file1 directory1
6 builtin cd ..
7 done
error
./mv.sh: line 4: cd: directory1: No such file or directory
mv: cannot stat `file1': No such file or directory
Is it possible that directory1 is a dangling symbolic link? For example:
mkdir foo
ln -s foo foolink
mv foo bar # foolink still points to foo but foo is gone!
cd foolink
# bash: cd: foolink: No such file or directory
Also, instead of
cd dir
mv foo subdir
cd ..
I would recommend the more succinct, and more importantly, safer version:
mv dir/foo dir/subdir/
Why is this safer? Imagine that dir doesn't exist:
cd dir # Fails
mv foo subdir # Oops! Now we're trying to move a file from the current directory
cd .. # Even bigger oops! Now we're even higher in the directory tree,
# and on the next iteration will be moving files around that we
# shouldn't be
(You could also avert this issue in this particular case by using set -o errexit but in general cd .. in scripts is dangerous, in my opinion.)
Also, as Ansgar Wiechers said, you should use find instead of trying to crawl the tree yourself.
I'd use find rather than trying to crawl the directory tree:
find . -type f -name "file1" -execdir mv {} directory1/ \;
This assumes that each directory with a file file1 has a subdirectory directory1.
I suppose the cd .. in line 6 lead you to another directory. You can check this by inserting builtin pwd between lines 6 and 7. This shows you in which directory you actually are after the cd ...
Maybe one of the directories is in fact a link to another directory? This could be the reason for landing somewhere you did not expect.
If the cd $i fails, you could also land in a wrong directory, this may happen if $i is not a directory or you don't have permission to explore it.

Resources