Linux how to copy but not overwrite? [closed] - linux

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
I want to cp a directory but I do not want to overwrite any existing files even it they are older than the copied files. And I want to do it completely noninteractive as this will be a part of a Crontab Bash script. Any ideas?

Taken from the man page:
-n, --no-clobber
do not overwrite an existing file (overrides a previous -i option)
Example:
cp -n myoldfile.txt mycopiedfile.txt

Consider using rsync.
rsync -a -v --ignore-existing src dst
As per comments rsync -a -v src dst is not correct because it will update existing files.

cp -n
Is what you want. See the man page.

This will work on RedHat:
false | cp -i source destination 2>/dev/null
Updating and not overwriting is something different.

For people that find that don't have an 'n' option (like me on RedHat) you can use cp -u to only write the file if the source is newer than the existing one (or there isn't an existing one).
[edit] As mentioned in the comments, this will overwrite older files, so isn't exactly what the OP wanted. Use ceving's answer for that.

Alpine linux: Below answer is only for case of single file: in alpine cp -n not working (and false | cp -i ... too) so solution working in my case that I found is:
if [ ! -f env.js ]; then cp env.example.js env.js; fi
In above example if env.js file not exists then we copy env.example.js to env.js.

Some version of cp do not have the --no-clobber option. In that case:
echo n | cp -vipr src/* dst

This works for me
yes n | cp -i src dest

Related

How to Rename Files in Linux [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 5 years ago.
Improve this question
I want to rename all files in selected directory using rename command or move command from :
_02_mp3_cbr_320.m4a?anghakamitoken=sc245ae5a454547.5
_02_mp3_fsgsfsdfsfdfdsfcbr_320.m4a?anghakamitoken=sc245.ae5a
to
1.m4a
2.m4a
If those files always have a sheme like this:
_02_mp3_ * _320.m4a?anghakamitoken= *
You can do it like that:
#!/bin/bash
COUNT=0
for f in ./"_02_mp3_"*"_320.m4a?anghakamitoken="*; do
mv $f "$((++COUNT)).m4a"
done
This will result in
1.m4a
2.m4a
Assuming the initial files are in the same directory as the bash script.
Try this with GNU Parallel. it basically uses GNU Parallel's job number ({#}) as the number for renaming:
parallel --dry-run -k mv {} {#}.m4a ::: *m4a*
Sample Output
mv _02_mp3_cbr_320.m4a\?anghakamitoken\=sc245ae5a454547.5 1.m4a
mv _02_mp3_fsgsfsdfsfdfdsfcbr_320.m4a\?anghakamitoken\=sc245.ae5a 2.m4a
If the commands look correct, remove the --dry-run part and run it again. The -k keeps the output in order. The {} refers to the current file.
Make a backup before using any commands you are unfamiliar with...
To rename any file in Linux using mv (move) command:
mv (cfr. "man mv")
In this case, you need to enter the following lines on the command line:
$mv _02_mp3_cbr_320.m4a?anghakamitoken=sc245ae5a454547.5 1.m4a
$mv _02_mp3_fsgsfsdfsfdfdsfcbr_320.m4a?anghakamitoken=sc245.ae5a 1.m4a
It is important that you refer to the manual when you know the command you must use, to understand how to use it.

Is there a safer command to delete files and directories other than rm -rf? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 6 years ago.
Improve this question
I've been reading how running rm -rf to delete files and directories isn't a good idea because of how dangerous it can be, but can't seem to find a consensus on how to safely delete files and directories through the terminal. Is there another command built into Linux that does this safely?
Consider using the -i or -I options, ie.
$ rm -i foo
$ rm -I foo
Those tell rm to be interactive, prompting you to confirm deletion of files.
From the rm(1) manpage:
-i prompt before every removal
-I prompt once before removing more than three files, or when
removing recursively; less intrusive than -i, while still giving
protection against most mistakes
For example:
$ mkdir -p ~/foo/{bar,baz} # make some dirs
$ touch ~/foo/{bar,baz}/{1,2,3} # add some empty files
$ rm -ir ~/ foo # note the "accidental" space between `~/` and `foo`
rm: descend into directory '/home/uz0r/'? y # haven't noticed yet...
rm: remove regular file '/home/uz0r/.bashrc'? # ...wait, what?
"Hold on... I told you to delete $HOME/foo, not $HOME! Or did I...?"
So you made a typo, but -i saved you from an accident. Now you can tell rm to stop, then try again after correcting the typo.
Be careful using -f! It counteracts the above safety nets by telling rm to "never prompt":
-f, --force
ignore nonexistent files and arguments, never prompt
Create yourself a trash bin for your deleted objects.
mkdir ~/trash
mv xyz ~/trash
You can recover, just be aware that some privileges may change on the files.

Linux - update multiple symlinks with a single command [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
When cloning an environment that utilizes symlinks, the symlinks are copied (from production to clone) but they are still pointing to the original (production) files. I want them to be pointing to the cloned files, like:
Original:
/production/symlink1 > /production/directory/file1
/production/foo/symlink2 > /production/directory/sub/file2
After clone (now):
/clone/symlink1 > /production/directory/file1
/clone/foo/symlink2 > /production/directory/sub/file2
I want:
/clone/symlink1 > /clone/directory/file1
/clone/foo/symlink2 > /clone/directory/sub/file2
Is there a way to achieve it with a single command?
Have you created the links yourself? If yes, you could create them with -r parameter. See man ln:
-r, --relative
create symbolic links relative to link location
If the links were pointing to absolute paths, they will always point to the same paths after copying. That's the beauty of absolute paths and I don't think you can work around that.
You can try to rewrite those links after copying though. For example if you create a script relink.sh like this:
#!/bin/bash
for link; do
target=$(readlink "$link")
[[ $target =~ ^/production ]] || continue
newtarget=$(echo $target | sed -e s?/production?/clone?)
echo ln -snf "$newtarget" "$link"
done
Pass a list of symlinks to this script, it will check if they are pointing to some path under /production, and recreate the link with /production replaced with /clone. You can call it like this for example:
find /clone -type l -exec ./relink.sh {} \;

How to download a file into a directory using curl or wget? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 6 years ago.
Improve this question
I know I can use the following 2 commands to download a file:
curl -O example.com/file.zip
wget example.com/file.zip
But I want them to go into a specific directory. So I can do the following:
curl -o mydir/file.zip example.com/file.zip
wget -O mydir/file.zip example.com/file.zip
Is there a way to not have to specify the filename? Something like this:
curl -dir mydir example.com/file.zip
The following line will download all the files to a directory mentioned by you.
wget -P /home/test www.xyz.com
Here the files will be downloaded to /home/test directory
I know this is an old question but it is possible to do what you ask with curl
rm directory/somefile.zip
rmdir directory
mkdir directory
curl --http1.1 http://example.com/somefile.zip --output directory/somefile.zip
first off if this was scripted you would need to make sure the file if it already exist is deleted then delete the directory then curl the download otherwise curl will fail with a file and directory already exist error.
The simplest way is to cd inside a subshell
(cd somedir; wget example.com/file.zip)
and you could make that a shell function (e.g. in your ~/.bashrc)
wgetinside() {
( cd $1 ; shift; wget $* )
}
then type wgetinside somedir http://example.com/file.zip
Short answer is no as curl and wget automatically writes to STDOUT. It does not have an option built into to place the download file into a directory.
-o/--output <file> Write output to <file> instead of stdout (Curl)
-O, --output-document=FILE write documents to FILE. (WGet)
But as it outputs to STDOUT natively it does give you programatic solutions such as the following:
i="YOURURL"; f=$(awk -F'/' '{print $NF}' <<< $i);curl $i > ~/$f
The first i will define your url (example.com/file.zip) as a variable. The f= part removed the URL and leaves /file.zip and then you curl that file ($i) to the directory (~) as the file name.

Prevent overwriting of files when using Scp [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 6 years ago.
Improve this question
I was copying some files using scp and i don't want to overwrite the already present files.
If i was using cp command, i think this can be done using cp -n.
Is there a similar option for scp, i went through the documentation of SCP and there seems to be no such option.
Is rsync or sftp the way to go solve this problem?
Addition Info:
OS: Ubuntu 12.04
rsync seems to be the solution to your problem. Here's an example I got from here:
rsync -avz foo:src/bar /data/tmp
The -a option will preserve permissions, directory structure, ownership, and symlinks. You can also specify any of those options individually as well.
-v and -z mean verbose and compress respectively. You don't really need them although -z is nice if you are copying large files.
I just found a simple hack. Mark the existing files as read-only.
rsync -avz --ignore-existing /source folder/* user#remoteserver:/dstfolder/
--ignore-existing will not overwrite the files on remote server or destination server*.
I've used rsync in the past for this, but found myself trying to grab from a windows box with CopSSH and no rsync :-( The following worked just fine for me, using file tests to eliminate the files that would be overwritten, and generating mutiple 'get' requests to an sftp instance.
( echo 'cd work/ftp/' ;
ssh <user>#<machine> 'cd work/ftp/ && ls -1 ITEM_SALE_SUMMARY_V.*.dat.xz' |
while read line; do [[ -f "$line" ]] || echo get "$line"; done
) | sftp <user>#<machine>
Just in case others need a non-rsync solution!
Just to supplement the other solutions:
For one ascii/bin file, you can do it with:
cat source_file | ssh host "test ! -f target_file && cat > target_file"
I did not test it but maybe first mountung via sshfs and then using cp will do the trick.
rsync over ssh it will have to be.

Resources