How to use scp with xargs? - linux

I am trying to move very big file from one host to another host. Also the file names are too large so I have to use xargs. Also all the sub directories need to be copied also
I am using the below command in the source host current directory
find . -name "*" -type f -print0 | xargs -0 scp -r UserName#host:/path/to/destination
but it is throwing below error
scp: /path/to/destination: not a regular file

you need to use {} to put the src filename before the destination. Here is the new command:
find . -name "*" -type f -print0 | xargs -0 -I {} scp -r {} UserName#host:/path/to/destination

Related

Linux: find a file in a directory, backup it with another name, replace it

In Linux I'm trying to find a file in a directory, backup it with another name and, then, replace it with another one.
I tried the first two actions with these commands
find foldername -name filename.html; -exec sed -i .bak;
but it's says
bash: -exec: command not found
Try this:
find foldername -name filename.html -exec cp -vp {}{,.bak} \; -exec truncate -s 0 {} \;
This uses find's exec option like it looks like you tried to use. Then cp copies the file (specified with {}) and appends .bak to the copy and preserves what it can with the p option:
preserve the specified attributes (default:
mode,ownership,timestamps), if possible additional attributes:
context, links, xattr, all
This leaves the original file in place as well.
You can do the following:
find . -name 'FILE_PATTERN_HERE' | xargs -I file_name cp file_name file_name.bkp
You can pipe the output of find command to cp using xargs. Here file_name acts as the output of find.
Example
find . -name 'logback.xml*'
Output:
./logback.xml
./apache-cassandra-3.11.1/conf/logback.xml
After running the command
find . -name 'logback.xml*' | xargs -I file_name cp file_name file_name.bkp
find . -name 'logback.xml*'
Output:
./logback.xml
./apache-cassandra-3.11.1/conf/logback.xml
./apache-cassandra-3.11.1/conf/logback.xml.bkp
./logback.xml.bkp

Linux find all files in sub directories and move them

I have a Linux-System where some users put files with ftp in a Directory. In this Directory there are sub-directories which the users can create. Now I need a script that searches for all files in those subdirectories and moves them in a single Directory (for backup). The Problem: The Sub directories shouldn´t be removed.
the directory for the users is /files/media/documents/
and the files have to be moved in the Directory /files/dump/. I don´t care about files in /files/media/documents/, they are already handled by another script.
I already tried this script:
for dir in /files/media/documents/
do
find "$dir/" -iname '*' -print0 | xargs -0 mv -t /files/dump/
done
Instead of iterating, you could just use find. In man-page there is a "-type" option documented, so for moving only files you could do:
find "/files/media/documents/" -type f -print0 | xargs -0 mv -t /files/dump/
You also won't like to find files in /files/media/documents/, but all sub-directories? Simply add "-mindepth":
find "/files/media/documents/" -type f -mindepth 1 -print0 | xargs -0 mv -t /files/dump/
Alternatively you could also use "-exec" to skip a second command (xargs):
find "/files/media/documents/" -type f -mindepth 1 -exec mv {} /files/dump/ \;

how to find and copy files in a sub directory from parent directory linux

I have several parent folders like GJ1, GJ2 etc. Each of these folders contain three images like GJ11_F.jpg, GJ11_P.jpg. I need to only display all the GJ11_F.jpg files including their respective parent directories.
find . -type f -name "*_F.jpg" | xargs cp -t ~/home/ubuntu/
but the above command will only copy the *_F.jpg files and not their respective parent directories GJ1.
Is xargs not the one im supposed to try?
I have also tried -
find . -name "*_F.jpg" -exec sh -c 'rsync -a "${0%/*}" ~/home/ubuntu/' {} \;
One easy way is to use tar which will deal with the directories automatically:
find . -type f -name "*_F.jpg" -print0 | tar c --null -T - | tar xC ~/home/ubuntu/
And here's a solution with a while loop:
find . -type f -name "*_F.jpg" -print0 |
while IFS= read -r -d '' file; do
mkdir -p ~/home/ubuntu/"$(dirname -- "$file")"
cp -ai -- "$file" ~/home/ubuntu/"$file"
done

Linux script Loop

I want to create a loop in Linux script that will go thru the folders in one directory and will copy photos to one folder and will overwrite photos that have the same name. Can anyone point me in the write direction?
find /path/to/source -type f -exec cp -f {} /path/to/destination \;
Would that work? Keep in mind, that will overwrite files without asking.
If you want it to confirm with you before overwriting, use the -i flag (for interactive mode) in the cp command.
find /path/to/source -type f | xargs -I {} file {} | grep <JPEG or image type> | cut -d ":" -f1 | xargs -I {} cp -rf {} /path/to/destination
With this you can find tune your copy with selecting only the image type.
Actually, you need not to loop through folders for finding photos using script, find command will do that job for you.
Try using find with xargs and cp
find source_dir -type f -iname '*.jpg' -print0 | xargs -0 -I {} cp -f {} dest_dir
Replace *.jpg with format of your photo files. (e.g. *.png etc.)
Note the use of -f option of cp, since you want to overwrite photos with the same name

Linux command for removing all ~ files

What command can I use in Linux to check if there is a file in a given directory (or its subdirectories) that contains a ~at the end of the file's name?
For example, if I'm at a directory called t which contains many subdirectories, etc, I would like to remove all files that end with a ~.
Watch out for filenames with spaces in them!
find ./ -name "*~" -type f -print0 | xargs -0 rm
with GNU find
find /path -type f -name "*~" -exec rm {} +
or
find /path -type f -name "*~" -delete
find ./ -name '*~' -print0 | xargs -0 rm -f
Here find will search the directory ./ and all sub directories, filtering for filenames that match the glob '*~' and printing them (with proper quoting courtesy of alberge). The results are passed to xargs to be appended to rm -f and the resulting string run in a shell. You can use multiple paths, and there are many other filters available (just read man find).
you can use a find, grep, rm combination, something like
find | grep "~" | xargs rm -f
Probably others have better ideas :)

Resources