Finding files due to misuse linux command mv - linux

how to find my files due to misuse mv?
for example, I change folder /var/lib/a
And I typed, "sudo mv /var/lib/b/* ./*"
then, I couldn't find my files nowhere
how can I find my files?

When you use the mv command all the files and folders in the following list are moved to the last place in your argument list.
By using the * you are first passing all elements in the folder /var/lib/b/ as arguments for mv and afterwards all elements in the current folder ./
If you have two files b1,b2 in /var/lib/b/ and two folders f1,f2 in ./ your command would be expanded to
mv /var/lib/b/b1 /var/lib/b/b2 ./f1 ./f2
That would mean all your files b1 and b2 should be moved to ./f2 now together with ./f1

Related

How to delete files from specific folders in linux?

So, I have a requirement to delete all files from specific folders within a directory. These are folders that end with "-outputs" in their names and I need to delete all files in those particular folders.
Is there a command in linux that lets you do that?
You can execute the following command:
rm $YOUR_PATH\*-outputs
Change $YOUR_PATH to the path where the files are located.
If you want to ignore nonexistent files and arguments, and avoid the prompt, you can use the -f option.
rm -f $YOUR_PATH\*-outputs
You can see the different rm options here:
rm Linual manual page

Is mv * a destructive command on a directory with 2 or more files? What other linux commands have similar behavior?

When I run mv * with no destination directory on a directory with say 10 files, I get an error as follows
root#tryit-apparent:~/test2# ls
file1.txt file10.txt file2.txt file3.txt file4.txt file5.txt file6.txt file7.txt file8.txt file9.txt
root#tryit-apparent:~/test2# mv *
mv: target 'file9.txt' is not a directory
When I run it on a directory with two files it overwrites the file with one just file.
root#tryit-apparent:~/test# ls
tempfile tempfile2
root#tryit-apparent:~/test# mv *
root#tryit-apparent:~/test# ls
tempfile2
I read the man pages but couldn't understand this behaviour. Would like to know what's causing this behavior and what's going on under the hood?
What other linux commands have such pitfalls and have destructive actions that are executed silently if the user is not aware of such behavior?
In Unix, unlike some other OSes, wildcards like * are expanded by the shell, before being passed to the command being run. So when you run mv * with tempfile and tempfile2 as the only files in the current directory, what the shell actually executes is mv tempfile tempfile2, which as normal will rename the first file over the second one, erasing the previous contents of tempfile2. The shell doesn't know or care that this command treats its last argument specially, and mv has no way of knowing that its two arguments came from a wildcard expansion. Hence the behavior you're seeing.
You can have similar issues even with more than two files. For instance, if you have files named tempfile1 through tempfile9 and a subdirectory named zyzzx, then mv * will move all your temp files into the zyzzx subdirectory.
Mostly, you just have to be aware that this is how wildcards work, and use caution with commands that treat one of their arguments specially (e.g. as a destination). cp is another one to watch out for, for the same reason. For interactive usage, you may want to get used to using the -i option to mv and cp, which asks for confirmation before overwriting files; or use an alias to make this the default.
Move is intented to move or rename a file or a directory, so you need a source and a destination.
If the path of the file is unchange then it becomes a rename operation.
If the path changes and the name remains the same it's a move.
You can do both by chaning the path and the name.
Man pages can be challenging to wrap your head around.
Googling can help: https://www.howtoforge.com/linux-mv-command/
Off the top of my head, you could do a cp operation followed by a rm to achieve similar results, but that's two steps, rather than one.

How to move a certain pattern of subfolders to another folder, keeping the structure using bash?

I have a set of folders like:
/path/to/group1/folder/number123
/path/to/group1/folder/number456
/path/to/group2/folder/number123
/path/to/group2/folder/number456
/path/to/group3/folder/number123
/path/to/group3/folder/number456
And I want to move folders that match /path/to/group*/folder/number123
to the base folder /path/toOther/ so that after the move it looks like:
/path/to/group1/folder/number456
/path/to/group2/folder/number456
/path/to/group3/folder/number456
/path/toOther/group1/folder/number123
/path/toOther/group2/folder/number123
/path/toOther/group3/folder/number123
Is there a way to do this with a move command and wild cards, or will it require more than a 1-liner?
If you don't mind writing a few lines:
cd /path/to
for f in group*/folder/number123
do
d="/path/toOther/${f%/*}"
mkdir -p "$d"
mv "$f" "$d/."
done
Of course you can combine the script into one line. (Or the bash will do this when you recall it with the Up key.)

How do I copy differing content files from one directory to another?

There exists two directories: a/ and b/.
I'd like to copy all the files(recursively) from a/ into b/.
However, I only want to copy over an a file if its content is different than the already existing b file. If the corresponding b file does not exist, then you would still copy over the a file.
*by "corresponding file", I mean a files with the same name and relative path from their parent directories.
note:
The reason I don't want to overwrite a b file with the same exact contents, is because the b directory is being monitored by another program, and I don't want the file date to change causing the program to do more work than required.
I'm essentially looking for a way to perform a cp -rf a/ b/ while performing a diff check on each file. If the file's are different, perform the copy; otherwise skip the copy.
I see that cp has an update flag:
-u, --update
copy only when the SOURCE file is newer than the destination file or when the
destination file is missing
but this will not work because I'm not concerned about newer files; I'm concerned about different file contents.
Any shell language will do.
I've been attempting to get this to work by injecting my diff check into a find command:
find a/ ??? -exec cp {} b \;
This doesn't seem like an uncommon thing to do between two directories, so I'm hoping there is an elegant command line solution as aposed to me having to write a python script.
You can achieve this using rsync. Files or directories will be updated only if there is any new update in source folder.
$rsync -av --progress sourcefolder destinationfolder

Recursively copy contents of directory to all target directories

I have a directory containing a set of subdirectories and files. I need to recursively copy all the content of this directory to all the subdirectories of another directory, also recursively.
How do I achieve this, preferably without using a script and only with the cp command?
You can write this in a script but you don't have to. Just write it line by line in the terminal:
# $TARGET is the directory containing subdirectories where you want to STORE the copies
# $SOURCE is the directory containing the subdirectories you want to COPY
for dir in $(ls $TARGET); do
cp -r $SOURCE/* $TARGET/$dir
done
Only uses cp and runs on both bash and zsh.
You can't. cp can copy multiple sources but will only copy to a single destination. You need to arrange to invoke cp multiple times - once per destination - for what you want to do; using, as you say, a loop or some other tool.
The first part of the command before the pipe instruct tar to create an archive of everything in the current directory and write it to standard output (the – in place of a file-name frequently indicates stdout).
tar cf - * | ( cd /target; tar xfp -)
The commands within parentheses cause the shell to change directory to the target directory and untar data from standard input. Since the cd and tar commands are contained within parentheses, their actions are performed together.
The -p option in the tar extraction command directs tar to preserve permission and ownership information, if possible given the user executing the command. If you are running the command as superuser, this option is turned on by default and can be omitted.
Also you can use the following command, but it seems to be quite slower than tar;
cp -a * /target

Resources