How do I create numbered backups?
Some GNU utils (e.g., mv and cp) can create numbered backups (foo.~1~).
Others (e.g., wget) cannot.
I would like to create numbered backups before running tools which overwrite files by default.
Here is a bash function which appears to do what I need:
backup(){ # back up the file, emacs style
file=$1
if test -f "${file}"; then
/bin/mv --backup=numbered "$(mktemp ${file}XXX)" "${file}"
/bin/rm "${file}"
fi
}
to be used, e.g., like this:
backup foo
curl http://.... > foo
I wonder if there is a better way.
backup cp mv
add a comment |
Some GNU utils (e.g., mv and cp) can create numbered backups (foo.~1~).
Others (e.g., wget) cannot.
I would like to create numbered backups before running tools which overwrite files by default.
Here is a bash function which appears to do what I need:
backup(){ # back up the file, emacs style
file=$1
if test -f "${file}"; then
/bin/mv --backup=numbered "$(mktemp ${file}XXX)" "${file}"
/bin/rm "${file}"
fi
}
to be used, e.g., like this:
backup foo
curl http://.... > foo
I wonder if there is a better way.
backup cp mv
Apart from the fact that the script obviously breaks with files that contain whitespace in their path—which can be easily fixed though—why are you asking if there's anything "better"? Better in what aspect?
– slhck
Aug 20 '13 at 20:58
1
@slhck: thanks for the bug catch - should be fixed. "better" - maybe I am missing something obvious and I do not need these 7 lines? maybe there is a trivial one-liner?
– sds
Aug 20 '13 at 21:14
add a comment |
Some GNU utils (e.g., mv and cp) can create numbered backups (foo.~1~).
Others (e.g., wget) cannot.
I would like to create numbered backups before running tools which overwrite files by default.
Here is a bash function which appears to do what I need:
backup(){ # back up the file, emacs style
file=$1
if test -f "${file}"; then
/bin/mv --backup=numbered "$(mktemp ${file}XXX)" "${file}"
/bin/rm "${file}"
fi
}
to be used, e.g., like this:
backup foo
curl http://.... > foo
I wonder if there is a better way.
backup cp mv
Some GNU utils (e.g., mv and cp) can create numbered backups (foo.~1~).
Others (e.g., wget) cannot.
I would like to create numbered backups before running tools which overwrite files by default.
Here is a bash function which appears to do what I need:
backup(){ # back up the file, emacs style
file=$1
if test -f "${file}"; then
/bin/mv --backup=numbered "$(mktemp ${file}XXX)" "${file}"
/bin/rm "${file}"
fi
}
to be used, e.g., like this:
backup foo
curl http://.... > foo
I wonder if there is a better way.
backup cp mv
backup cp mv
edited Aug 20 '13 at 21:11
sds
asked Aug 20 '13 at 20:18
sdssds
1,24521430
1,24521430
Apart from the fact that the script obviously breaks with files that contain whitespace in their path—which can be easily fixed though—why are you asking if there's anything "better"? Better in what aspect?
– slhck
Aug 20 '13 at 20:58
1
@slhck: thanks for the bug catch - should be fixed. "better" - maybe I am missing something obvious and I do not need these 7 lines? maybe there is a trivial one-liner?
– sds
Aug 20 '13 at 21:14
add a comment |
Apart from the fact that the script obviously breaks with files that contain whitespace in their path—which can be easily fixed though—why are you asking if there's anything "better"? Better in what aspect?
– slhck
Aug 20 '13 at 20:58
1
@slhck: thanks for the bug catch - should be fixed. "better" - maybe I am missing something obvious and I do not need these 7 lines? maybe there is a trivial one-liner?
– sds
Aug 20 '13 at 21:14
Apart from the fact that the script obviously breaks with files that contain whitespace in their path—which can be easily fixed though—why are you asking if there's anything "better"? Better in what aspect?
– slhck
Aug 20 '13 at 20:58
Apart from the fact that the script obviously breaks with files that contain whitespace in their path—which can be easily fixed though—why are you asking if there's anything "better"? Better in what aspect?
– slhck
Aug 20 '13 at 20:58
1
1
@slhck: thanks for the bug catch - should be fixed. "better" - maybe I am missing something obvious and I do not need these 7 lines? maybe there is a trivial one-liner?
– sds
Aug 20 '13 at 21:14
@slhck: thanks for the bug catch - should be fixed. "better" - maybe I am missing something obvious and I do not need these 7 lines? maybe there is a trivial one-liner?
– sds
Aug 20 '13 at 21:14
add a comment |
2 Answers
2
active
oldest
votes
A small improvement over the OP's solution to make it more generally usefull:
- Works with directories.
- The
mktempargument might need quotes, too. - I'd
&&the commands in order not to get an error message frommvifmktempfails, etc. - Added option / argument separators
--in case of filenames which start with a dash.
backup(){ # back up the file, emacs style
local file=$1
local tmp
if test -e "${file}"; then
tmp=$(mktemp -- "${file}XXX") && /bin/mv --backup=numbered --no-target-dir -- "$tmp" "${file}" && /bin/rm -- "${file}"
fi
}
BTW, cp supports making a numbered backup with source == target.
> cp -v --backup=t --force a a
'a' -> 'a.~4~'
add a comment |
Still not exactly a one liner, but you get closer with one single call to perl together with its powerful e option (ie. execute the substitution part):
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
Notice the and exit what prevents perl to print the matching count that otherwise pollutes the name.
You may also want to add 2>/dev/null to the end of the line to keep it quiet when the file does not exist.
This is more complex than my solution; it does not use the--backupoption ofmv, it emulates it withperl.
– sds
Aug 21 '13 at 13:16
add a comment |
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "3"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f634390%2fhow-do-i-create-numbered-backups%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
A small improvement over the OP's solution to make it more generally usefull:
- Works with directories.
- The
mktempargument might need quotes, too. - I'd
&&the commands in order not to get an error message frommvifmktempfails, etc. - Added option / argument separators
--in case of filenames which start with a dash.
backup(){ # back up the file, emacs style
local file=$1
local tmp
if test -e "${file}"; then
tmp=$(mktemp -- "${file}XXX") && /bin/mv --backup=numbered --no-target-dir -- "$tmp" "${file}" && /bin/rm -- "${file}"
fi
}
BTW, cp supports making a numbered backup with source == target.
> cp -v --backup=t --force a a
'a' -> 'a.~4~'
add a comment |
A small improvement over the OP's solution to make it more generally usefull:
- Works with directories.
- The
mktempargument might need quotes, too. - I'd
&&the commands in order not to get an error message frommvifmktempfails, etc. - Added option / argument separators
--in case of filenames which start with a dash.
backup(){ # back up the file, emacs style
local file=$1
local tmp
if test -e "${file}"; then
tmp=$(mktemp -- "${file}XXX") && /bin/mv --backup=numbered --no-target-dir -- "$tmp" "${file}" && /bin/rm -- "${file}"
fi
}
BTW, cp supports making a numbered backup with source == target.
> cp -v --backup=t --force a a
'a' -> 'a.~4~'
add a comment |
A small improvement over the OP's solution to make it more generally usefull:
- Works with directories.
- The
mktempargument might need quotes, too. - I'd
&&the commands in order not to get an error message frommvifmktempfails, etc. - Added option / argument separators
--in case of filenames which start with a dash.
backup(){ # back up the file, emacs style
local file=$1
local tmp
if test -e "${file}"; then
tmp=$(mktemp -- "${file}XXX") && /bin/mv --backup=numbered --no-target-dir -- "$tmp" "${file}" && /bin/rm -- "${file}"
fi
}
BTW, cp supports making a numbered backup with source == target.
> cp -v --backup=t --force a a
'a' -> 'a.~4~'
A small improvement over the OP's solution to make it more generally usefull:
- Works with directories.
- The
mktempargument might need quotes, too. - I'd
&&the commands in order not to get an error message frommvifmktempfails, etc. - Added option / argument separators
--in case of filenames which start with a dash.
backup(){ # back up the file, emacs style
local file=$1
local tmp
if test -e "${file}"; then
tmp=$(mktemp -- "${file}XXX") && /bin/mv --backup=numbered --no-target-dir -- "$tmp" "${file}" && /bin/rm -- "${file}"
fi
}
BTW, cp supports making a numbered backup with source == target.
> cp -v --backup=t --force a a
'a' -> 'a.~4~'
answered Feb 16 at 22:00
EndlosSchleifeEndlosSchleife
513
513
add a comment |
add a comment |
Still not exactly a one liner, but you get closer with one single call to perl together with its powerful e option (ie. execute the substitution part):
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
Notice the and exit what prevents perl to print the matching count that otherwise pollutes the name.
You may also want to add 2>/dev/null to the end of the line to keep it quiet when the file does not exist.
This is more complex than my solution; it does not use the--backupoption ofmv, it emulates it withperl.
– sds
Aug 21 '13 at 13:16
add a comment |
Still not exactly a one liner, but you get closer with one single call to perl together with its powerful e option (ie. execute the substitution part):
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
Notice the and exit what prevents perl to print the matching count that otherwise pollutes the name.
You may also want to add 2>/dev/null to the end of the line to keep it quiet when the file does not exist.
This is more complex than my solution; it does not use the--backupoption ofmv, it emulates it withperl.
– sds
Aug 21 '13 at 13:16
add a comment |
Still not exactly a one liner, but you get closer with one single call to perl together with its powerful e option (ie. execute the substitution part):
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
Notice the and exit what prevents perl to print the matching count that otherwise pollutes the name.
You may also want to add 2>/dev/null to the end of the line to keep it quiet when the file does not exist.
Still not exactly a one liner, but you get closer with one single call to perl together with its powerful e option (ie. execute the substitution part):
backup(){
mv "$1" "$(echo $1 |perl -pe '~s|(.*?)(~([0-9]*)~)?$|print "$1~".(${3}+1)."~"|e and exit')"
}
Notice the and exit what prevents perl to print the matching count that otherwise pollutes the name.
You may also want to add 2>/dev/null to the end of the line to keep it quiet when the file does not exist.
answered Aug 21 '13 at 12:06
MoonCactusMoonCactus
1135
1135
This is more complex than my solution; it does not use the--backupoption ofmv, it emulates it withperl.
– sds
Aug 21 '13 at 13:16
add a comment |
This is more complex than my solution; it does not use the--backupoption ofmv, it emulates it withperl.
– sds
Aug 21 '13 at 13:16
This is more complex than my solution; it does not use the
--backup option of mv, it emulates it with perl.– sds
Aug 21 '13 at 13:16
This is more complex than my solution; it does not use the
--backup option of mv, it emulates it with perl.– sds
Aug 21 '13 at 13:16
add a comment |
Thanks for contributing an answer to Super User!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f634390%2fhow-do-i-create-numbered-backups%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown

Apart from the fact that the script obviously breaks with files that contain whitespace in their path—which can be easily fixed though—why are you asking if there's anything "better"? Better in what aspect?
– slhck
Aug 20 '13 at 20:58
1
@slhck: thanks for the bug catch - should be fixed. "better" - maybe I am missing something obvious and I do not need these 7 lines? maybe there is a trivial one-liner?
– sds
Aug 20 '13 at 21:14