How can I permanently correct a typo in my last bash command?
It's not uncommon that I make a typo when entering commands in my bash interactive shell. I'd like to be able to correct the typo in my bash history so that the incorrect command does not pollute it and lead me to accidentally re-execute it later. In particular, I'd like to edit the last command.
There are quite a number of questions asking about how to prevent accidentally editing bash history. I want the opposite: I want to explicitly edit history.
Based on some of the explanations from the referenced questions, I tried doing:
$ echo foo
pressing Up, changing it to:
$ echo foobar
pressing Down, but that does nothing, and if I then press Enter, it will execute the modified command and leave both
echo foo
echo foobar
in my history.
I am aware that I can manually delete history entries with history -d
, but I haven't devised a good way to use that conveniently. I don't want to make a shell function to unconditionally delete the last history entry because I still want to be able to use Up to load the last entry so that I can correct it. I could make the correction and then delete the second-to-last history entry, but that feels clumsy and it's particularly annoying for a long-running command since I'd either need to remember to perform extra steps later or would need to temporarily suspend it, do those steps, and resume.
What I want:
Ideally what I'd like to be able to do is to press Up, make a correction to my previous command, and press some special keybinding or add some magic token to the command-line to cause it to replace the history entry when executed.
Also acceptable would be to press some other key sequence to retrieve and edit a command from history (similar to Ctrl+R) that overwrites the history entry when executed.
A robust shell function that removes the second-to-last history entry would be tolerable but non-ideal.
I imagine that surely other people make typos too and are similarly annoyed when such commands pollute their history. What do other people do?
bash command-history readline
|
show 1 more comment
It's not uncommon that I make a typo when entering commands in my bash interactive shell. I'd like to be able to correct the typo in my bash history so that the incorrect command does not pollute it and lead me to accidentally re-execute it later. In particular, I'd like to edit the last command.
There are quite a number of questions asking about how to prevent accidentally editing bash history. I want the opposite: I want to explicitly edit history.
Based on some of the explanations from the referenced questions, I tried doing:
$ echo foo
pressing Up, changing it to:
$ echo foobar
pressing Down, but that does nothing, and if I then press Enter, it will execute the modified command and leave both
echo foo
echo foobar
in my history.
I am aware that I can manually delete history entries with history -d
, but I haven't devised a good way to use that conveniently. I don't want to make a shell function to unconditionally delete the last history entry because I still want to be able to use Up to load the last entry so that I can correct it. I could make the correction and then delete the second-to-last history entry, but that feels clumsy and it's particularly annoying for a long-running command since I'd either need to remember to perform extra steps later or would need to temporarily suspend it, do those steps, and resume.
What I want:
Ideally what I'd like to be able to do is to press Up, make a correction to my previous command, and press some special keybinding or add some magic token to the command-line to cause it to replace the history entry when executed.
Also acceptable would be to press some other key sequence to retrieve and edit a command from history (similar to Ctrl+R) that overwrites the history entry when executed.
A robust shell function that removes the second-to-last history entry would be tolerable but non-ideal.
I imagine that surely other people make typos too and are similarly annoyed when such commands pollute their history. What do other people do?
bash command-history readline
Possible duplicate of How to remove a single line from history?
– Ipor Sircer
Jul 17 '18 at 2:46
I already stated that I know how to remove a single history line, but by itself those mechanisms (history -d
or editing.bash_history
in an editor) are too inconvenient to use. I'm specifically asking for more convenient approaches, particularly in the context of correcting an existing line (which might not entail complete removal of the original).
– jamesdlin
Jul 17 '18 at 2:59
If bash doesn't support replacing lines, then you have to write this feature yourself. The good news: bash is opensource.
– Ipor Sircer
Jul 17 '18 at 3:05
@IporSircer I'm asking if bash supports replacing lines. Clearly it has some mechanism for doing so since there are a lot of questions asking how to prevent that from happening. Is it unreasonable to ask if there's a way to harness that power for good instead of evil?
– jamesdlin
Jul 17 '18 at 3:07
Read the fine manual (man bash
); all features are documented. There are no hidden secrets.
– Ipor Sircer
Jul 17 '18 at 3:08
|
show 1 more comment
It's not uncommon that I make a typo when entering commands in my bash interactive shell. I'd like to be able to correct the typo in my bash history so that the incorrect command does not pollute it and lead me to accidentally re-execute it later. In particular, I'd like to edit the last command.
There are quite a number of questions asking about how to prevent accidentally editing bash history. I want the opposite: I want to explicitly edit history.
Based on some of the explanations from the referenced questions, I tried doing:
$ echo foo
pressing Up, changing it to:
$ echo foobar
pressing Down, but that does nothing, and if I then press Enter, it will execute the modified command and leave both
echo foo
echo foobar
in my history.
I am aware that I can manually delete history entries with history -d
, but I haven't devised a good way to use that conveniently. I don't want to make a shell function to unconditionally delete the last history entry because I still want to be able to use Up to load the last entry so that I can correct it. I could make the correction and then delete the second-to-last history entry, but that feels clumsy and it's particularly annoying for a long-running command since I'd either need to remember to perform extra steps later or would need to temporarily suspend it, do those steps, and resume.
What I want:
Ideally what I'd like to be able to do is to press Up, make a correction to my previous command, and press some special keybinding or add some magic token to the command-line to cause it to replace the history entry when executed.
Also acceptable would be to press some other key sequence to retrieve and edit a command from history (similar to Ctrl+R) that overwrites the history entry when executed.
A robust shell function that removes the second-to-last history entry would be tolerable but non-ideal.
I imagine that surely other people make typos too and are similarly annoyed when such commands pollute their history. What do other people do?
bash command-history readline
It's not uncommon that I make a typo when entering commands in my bash interactive shell. I'd like to be able to correct the typo in my bash history so that the incorrect command does not pollute it and lead me to accidentally re-execute it later. In particular, I'd like to edit the last command.
There are quite a number of questions asking about how to prevent accidentally editing bash history. I want the opposite: I want to explicitly edit history.
Based on some of the explanations from the referenced questions, I tried doing:
$ echo foo
pressing Up, changing it to:
$ echo foobar
pressing Down, but that does nothing, and if I then press Enter, it will execute the modified command and leave both
echo foo
echo foobar
in my history.
I am aware that I can manually delete history entries with history -d
, but I haven't devised a good way to use that conveniently. I don't want to make a shell function to unconditionally delete the last history entry because I still want to be able to use Up to load the last entry so that I can correct it. I could make the correction and then delete the second-to-last history entry, but that feels clumsy and it's particularly annoying for a long-running command since I'd either need to remember to perform extra steps later or would need to temporarily suspend it, do those steps, and resume.
What I want:
Ideally what I'd like to be able to do is to press Up, make a correction to my previous command, and press some special keybinding or add some magic token to the command-line to cause it to replace the history entry when executed.
Also acceptable would be to press some other key sequence to retrieve and edit a command from history (similar to Ctrl+R) that overwrites the history entry when executed.
A robust shell function that removes the second-to-last history entry would be tolerable but non-ideal.
I imagine that surely other people make typos too and are similarly annoyed when such commands pollute their history. What do other people do?
bash command-history readline
bash command-history readline
edited Jul 17 '18 at 3:17
jamesdlin
asked Jul 17 '18 at 2:40
jamesdlinjamesdlin
554413
554413
Possible duplicate of How to remove a single line from history?
– Ipor Sircer
Jul 17 '18 at 2:46
I already stated that I know how to remove a single history line, but by itself those mechanisms (history -d
or editing.bash_history
in an editor) are too inconvenient to use. I'm specifically asking for more convenient approaches, particularly in the context of correcting an existing line (which might not entail complete removal of the original).
– jamesdlin
Jul 17 '18 at 2:59
If bash doesn't support replacing lines, then you have to write this feature yourself. The good news: bash is opensource.
– Ipor Sircer
Jul 17 '18 at 3:05
@IporSircer I'm asking if bash supports replacing lines. Clearly it has some mechanism for doing so since there are a lot of questions asking how to prevent that from happening. Is it unreasonable to ask if there's a way to harness that power for good instead of evil?
– jamesdlin
Jul 17 '18 at 3:07
Read the fine manual (man bash
); all features are documented. There are no hidden secrets.
– Ipor Sircer
Jul 17 '18 at 3:08
|
show 1 more comment
Possible duplicate of How to remove a single line from history?
– Ipor Sircer
Jul 17 '18 at 2:46
I already stated that I know how to remove a single history line, but by itself those mechanisms (history -d
or editing.bash_history
in an editor) are too inconvenient to use. I'm specifically asking for more convenient approaches, particularly in the context of correcting an existing line (which might not entail complete removal of the original).
– jamesdlin
Jul 17 '18 at 2:59
If bash doesn't support replacing lines, then you have to write this feature yourself. The good news: bash is opensource.
– Ipor Sircer
Jul 17 '18 at 3:05
@IporSircer I'm asking if bash supports replacing lines. Clearly it has some mechanism for doing so since there are a lot of questions asking how to prevent that from happening. Is it unreasonable to ask if there's a way to harness that power for good instead of evil?
– jamesdlin
Jul 17 '18 at 3:07
Read the fine manual (man bash
); all features are documented. There are no hidden secrets.
– Ipor Sircer
Jul 17 '18 at 3:08
Possible duplicate of How to remove a single line from history?
– Ipor Sircer
Jul 17 '18 at 2:46
Possible duplicate of How to remove a single line from history?
– Ipor Sircer
Jul 17 '18 at 2:46
I already stated that I know how to remove a single history line, but by itself those mechanisms (
history -d
or editing .bash_history
in an editor) are too inconvenient to use. I'm specifically asking for more convenient approaches, particularly in the context of correcting an existing line (which might not entail complete removal of the original).– jamesdlin
Jul 17 '18 at 2:59
I already stated that I know how to remove a single history line, but by itself those mechanisms (
history -d
or editing .bash_history
in an editor) are too inconvenient to use. I'm specifically asking for more convenient approaches, particularly in the context of correcting an existing line (which might not entail complete removal of the original).– jamesdlin
Jul 17 '18 at 2:59
If bash doesn't support replacing lines, then you have to write this feature yourself. The good news: bash is opensource.
– Ipor Sircer
Jul 17 '18 at 3:05
If bash doesn't support replacing lines, then you have to write this feature yourself. The good news: bash is opensource.
– Ipor Sircer
Jul 17 '18 at 3:05
@IporSircer I'm asking if bash supports replacing lines. Clearly it has some mechanism for doing so since there are a lot of questions asking how to prevent that from happening. Is it unreasonable to ask if there's a way to harness that power for good instead of evil?
– jamesdlin
Jul 17 '18 at 3:07
@IporSircer I'm asking if bash supports replacing lines. Clearly it has some mechanism for doing so since there are a lot of questions asking how to prevent that from happening. Is it unreasonable to ask if there's a way to harness that power for good instead of evil?
– jamesdlin
Jul 17 '18 at 3:07
Read the fine manual (
man bash
); all features are documented. There are no hidden secrets.– Ipor Sircer
Jul 17 '18 at 3:08
Read the fine manual (
man bash
); all features are documented. There are no hidden secrets.– Ipor Sircer
Jul 17 '18 at 3:08
|
show 1 more comment
2 Answers
2
active
oldest
votes
Option #1 - Manually
I'd simply open the ~/.bash_history
file in an editor such as vim
and make whatever changes you need to that file and save.
$ vim ~/.bash_history
Before editing it make sure your current terminals history is committed to this file as well:
$ history -a
Keep in mind that your history file is located where ever this environment variable is pointing to:
$ echo $HISTFILE
/Users/user1/.bash_history
Option #2 - HSTR
There's a CLI tool called HSTR that you can use to manage your ~/.bash_history
file in a more systematic way. The main website for HSTR was videos and good details on using it.
It also mentions this blurb:
HSTR can also manage your command history (for instance you can remove commands that are obsolete or contain a sensitive information) or bookmark your favorite commands.
Refer to the full docs for more on this: HSTR DOCUMENTATION.
References
- Remove a certain line from Bash history file
If I findhistory -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.
– jamesdlin
Jul 17 '18 at 3:04
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
@jamesdlin - your Q reminded my ofhstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.
– slm♦
Jul 17 '18 at 3:16
1
I've adjusted my question.hstr
looks interesting! I'll look into that. Thanks!
– jamesdlin
Jul 17 '18 at 3:17
add a comment |
HSTR seemed appealing but turned out to be a bit too heavyweight for my taste.
I instead wrote my own bash function:
# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
# historysub SEARCH [REPLACEMENT]
# historysub -d SEARCH
#
# REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
# -d removes the last command matching SEARCH from the history without
# executing a new command.
historysub()
{
local delete=0
local usage=0
local OPTIND=1
while getopts ":hd" option; do
case "${option}" in
d) delete=1 ;;
h) usage=1 ;;
?) usage=2 ;;
esac
done
shift $((OPTIND - 1))
local search="${1}"
local replacement="${2}"
usage_text=
usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]n"
usage_text+=" ${FUNCNAME[0]} -d SEARCHn"
if (( usage )); then
echo -e "${usage_text}"
return $(( usage - 1 ))
fi
if [[ -z "${search}" ]]; then
echo -e "${usage_text}" >&2
return 1
fi
# Find the last matching history entry (excluding ourself).
local hist_info
hist_info=$(HISTTIMEFORMAT="" history | grep -F -- "${search}" | grep -vF -- "${FUNCNAME[0]}" | tail -n 1)
if [[ -z "${hist_info}" ]]; then
echo "${FUNCNAME[0]}: "${search}" not found." >&2
return 1
fi
local re='^[ t]*([0-9]+)[ t]+(.+)$'
local hist_num hist_cmd
hist_num=$(sed -E "s/${re}/1/" <<< "${hist_info}")
hist_cmd=$(sed -E "s/${re}/2/" <<< "${hist_info}")
history -d "${hist_num}"
if (( delete )); then
echo "Removed: ${hist_cmd}"
return 0
fi
local cmd="${hist_cmd/${search}/${replacement}}"
echo "${cmd}"
# Add the new command to the history.
history -s ${cmd}
eval ${cmd}
}
So now I can run historysub TYPO CORRECTION
to re-execute a command with a correction. It's not as good as being able to interactively edit the old command, but I think it should be good enough for my needs.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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%2funix.stackexchange.com%2fquestions%2f456671%2fhow-can-i-permanently-correct-a-typo-in-my-last-bash-command%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
Option #1 - Manually
I'd simply open the ~/.bash_history
file in an editor such as vim
and make whatever changes you need to that file and save.
$ vim ~/.bash_history
Before editing it make sure your current terminals history is committed to this file as well:
$ history -a
Keep in mind that your history file is located where ever this environment variable is pointing to:
$ echo $HISTFILE
/Users/user1/.bash_history
Option #2 - HSTR
There's a CLI tool called HSTR that you can use to manage your ~/.bash_history
file in a more systematic way. The main website for HSTR was videos and good details on using it.
It also mentions this blurb:
HSTR can also manage your command history (for instance you can remove commands that are obsolete or contain a sensitive information) or bookmark your favorite commands.
Refer to the full docs for more on this: HSTR DOCUMENTATION.
References
- Remove a certain line from Bash history file
If I findhistory -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.
– jamesdlin
Jul 17 '18 at 3:04
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
@jamesdlin - your Q reminded my ofhstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.
– slm♦
Jul 17 '18 at 3:16
1
I've adjusted my question.hstr
looks interesting! I'll look into that. Thanks!
– jamesdlin
Jul 17 '18 at 3:17
add a comment |
Option #1 - Manually
I'd simply open the ~/.bash_history
file in an editor such as vim
and make whatever changes you need to that file and save.
$ vim ~/.bash_history
Before editing it make sure your current terminals history is committed to this file as well:
$ history -a
Keep in mind that your history file is located where ever this environment variable is pointing to:
$ echo $HISTFILE
/Users/user1/.bash_history
Option #2 - HSTR
There's a CLI tool called HSTR that you can use to manage your ~/.bash_history
file in a more systematic way. The main website for HSTR was videos and good details on using it.
It also mentions this blurb:
HSTR can also manage your command history (for instance you can remove commands that are obsolete or contain a sensitive information) or bookmark your favorite commands.
Refer to the full docs for more on this: HSTR DOCUMENTATION.
References
- Remove a certain line from Bash history file
If I findhistory -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.
– jamesdlin
Jul 17 '18 at 3:04
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
@jamesdlin - your Q reminded my ofhstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.
– slm♦
Jul 17 '18 at 3:16
1
I've adjusted my question.hstr
looks interesting! I'll look into that. Thanks!
– jamesdlin
Jul 17 '18 at 3:17
add a comment |
Option #1 - Manually
I'd simply open the ~/.bash_history
file in an editor such as vim
and make whatever changes you need to that file and save.
$ vim ~/.bash_history
Before editing it make sure your current terminals history is committed to this file as well:
$ history -a
Keep in mind that your history file is located where ever this environment variable is pointing to:
$ echo $HISTFILE
/Users/user1/.bash_history
Option #2 - HSTR
There's a CLI tool called HSTR that you can use to manage your ~/.bash_history
file in a more systematic way. The main website for HSTR was videos and good details on using it.
It also mentions this blurb:
HSTR can also manage your command history (for instance you can remove commands that are obsolete or contain a sensitive information) or bookmark your favorite commands.
Refer to the full docs for more on this: HSTR DOCUMENTATION.
References
- Remove a certain line from Bash history file
Option #1 - Manually
I'd simply open the ~/.bash_history
file in an editor such as vim
and make whatever changes you need to that file and save.
$ vim ~/.bash_history
Before editing it make sure your current terminals history is committed to this file as well:
$ history -a
Keep in mind that your history file is located where ever this environment variable is pointing to:
$ echo $HISTFILE
/Users/user1/.bash_history
Option #2 - HSTR
There's a CLI tool called HSTR that you can use to manage your ~/.bash_history
file in a more systematic way. The main website for HSTR was videos and good details on using it.
It also mentions this blurb:
HSTR can also manage your command history (for instance you can remove commands that are obsolete or contain a sensitive information) or bookmark your favorite commands.
Refer to the full docs for more on this: HSTR DOCUMENTATION.
References
- Remove a certain line from Bash history file
edited Jul 17 '18 at 3:18
answered Jul 17 '18 at 2:45
slm♦slm
253k71535687
253k71535687
If I findhistory -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.
– jamesdlin
Jul 17 '18 at 3:04
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
@jamesdlin - your Q reminded my ofhstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.
– slm♦
Jul 17 '18 at 3:16
1
I've adjusted my question.hstr
looks interesting! I'll look into that. Thanks!
– jamesdlin
Jul 17 '18 at 3:17
add a comment |
If I findhistory -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.
– jamesdlin
Jul 17 '18 at 3:04
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
@jamesdlin - your Q reminded my ofhstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.
– slm♦
Jul 17 '18 at 3:16
1
I've adjusted my question.hstr
looks interesting! I'll look into that. Thanks!
– jamesdlin
Jul 17 '18 at 3:17
If I find
history -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.– jamesdlin
Jul 17 '18 at 3:04
If I find
history -d
too inconvenient to use, this isn't really any better, especially if I need to remember to do those steps after I execute the corrected command.– jamesdlin
Jul 17 '18 at 3:04
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
Can you please add to your question what you actually want as a potential solution then? A shell function to run? Not sure how to address your question beyond showing you the bits and you can roll them into whatever solution works best for your style.
– slm♦
Jul 17 '18 at 3:10
@jamesdlin - your Q reminded my of
hstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.– slm♦
Jul 17 '18 at 3:16
@jamesdlin - your Q reminded my of
hstr
might be something worth a look for your use case. It sets up a keybinding that you can use to kill the last run command from history - github.com/dvorka/hstr/blob/master/DOCUMENTATION.md.– slm♦
Jul 17 '18 at 3:16
1
1
I've adjusted my question.
hstr
looks interesting! I'll look into that. Thanks!– jamesdlin
Jul 17 '18 at 3:17
I've adjusted my question.
hstr
looks interesting! I'll look into that. Thanks!– jamesdlin
Jul 17 '18 at 3:17
add a comment |
HSTR seemed appealing but turned out to be a bit too heavyweight for my taste.
I instead wrote my own bash function:
# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
# historysub SEARCH [REPLACEMENT]
# historysub -d SEARCH
#
# REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
# -d removes the last command matching SEARCH from the history without
# executing a new command.
historysub()
{
local delete=0
local usage=0
local OPTIND=1
while getopts ":hd" option; do
case "${option}" in
d) delete=1 ;;
h) usage=1 ;;
?) usage=2 ;;
esac
done
shift $((OPTIND - 1))
local search="${1}"
local replacement="${2}"
usage_text=
usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]n"
usage_text+=" ${FUNCNAME[0]} -d SEARCHn"
if (( usage )); then
echo -e "${usage_text}"
return $(( usage - 1 ))
fi
if [[ -z "${search}" ]]; then
echo -e "${usage_text}" >&2
return 1
fi
# Find the last matching history entry (excluding ourself).
local hist_info
hist_info=$(HISTTIMEFORMAT="" history | grep -F -- "${search}" | grep -vF -- "${FUNCNAME[0]}" | tail -n 1)
if [[ -z "${hist_info}" ]]; then
echo "${FUNCNAME[0]}: "${search}" not found." >&2
return 1
fi
local re='^[ t]*([0-9]+)[ t]+(.+)$'
local hist_num hist_cmd
hist_num=$(sed -E "s/${re}/1/" <<< "${hist_info}")
hist_cmd=$(sed -E "s/${re}/2/" <<< "${hist_info}")
history -d "${hist_num}"
if (( delete )); then
echo "Removed: ${hist_cmd}"
return 0
fi
local cmd="${hist_cmd/${search}/${replacement}}"
echo "${cmd}"
# Add the new command to the history.
history -s ${cmd}
eval ${cmd}
}
So now I can run historysub TYPO CORRECTION
to re-execute a command with a correction. It's not as good as being able to interactively edit the old command, but I think it should be good enough for my needs.
add a comment |
HSTR seemed appealing but turned out to be a bit too heavyweight for my taste.
I instead wrote my own bash function:
# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
# historysub SEARCH [REPLACEMENT]
# historysub -d SEARCH
#
# REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
# -d removes the last command matching SEARCH from the history without
# executing a new command.
historysub()
{
local delete=0
local usage=0
local OPTIND=1
while getopts ":hd" option; do
case "${option}" in
d) delete=1 ;;
h) usage=1 ;;
?) usage=2 ;;
esac
done
shift $((OPTIND - 1))
local search="${1}"
local replacement="${2}"
usage_text=
usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]n"
usage_text+=" ${FUNCNAME[0]} -d SEARCHn"
if (( usage )); then
echo -e "${usage_text}"
return $(( usage - 1 ))
fi
if [[ -z "${search}" ]]; then
echo -e "${usage_text}" >&2
return 1
fi
# Find the last matching history entry (excluding ourself).
local hist_info
hist_info=$(HISTTIMEFORMAT="" history | grep -F -- "${search}" | grep -vF -- "${FUNCNAME[0]}" | tail -n 1)
if [[ -z "${hist_info}" ]]; then
echo "${FUNCNAME[0]}: "${search}" not found." >&2
return 1
fi
local re='^[ t]*([0-9]+)[ t]+(.+)$'
local hist_num hist_cmd
hist_num=$(sed -E "s/${re}/1/" <<< "${hist_info}")
hist_cmd=$(sed -E "s/${re}/2/" <<< "${hist_info}")
history -d "${hist_num}"
if (( delete )); then
echo "Removed: ${hist_cmd}"
return 0
fi
local cmd="${hist_cmd/${search}/${replacement}}"
echo "${cmd}"
# Add the new command to the history.
history -s ${cmd}
eval ${cmd}
}
So now I can run historysub TYPO CORRECTION
to re-execute a command with a correction. It's not as good as being able to interactively edit the old command, but I think it should be good enough for my needs.
add a comment |
HSTR seemed appealing but turned out to be a bit too heavyweight for my taste.
I instead wrote my own bash function:
# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
# historysub SEARCH [REPLACEMENT]
# historysub -d SEARCH
#
# REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
# -d removes the last command matching SEARCH from the history without
# executing a new command.
historysub()
{
local delete=0
local usage=0
local OPTIND=1
while getopts ":hd" option; do
case "${option}" in
d) delete=1 ;;
h) usage=1 ;;
?) usage=2 ;;
esac
done
shift $((OPTIND - 1))
local search="${1}"
local replacement="${2}"
usage_text=
usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]n"
usage_text+=" ${FUNCNAME[0]} -d SEARCHn"
if (( usage )); then
echo -e "${usage_text}"
return $(( usage - 1 ))
fi
if [[ -z "${search}" ]]; then
echo -e "${usage_text}" >&2
return 1
fi
# Find the last matching history entry (excluding ourself).
local hist_info
hist_info=$(HISTTIMEFORMAT="" history | grep -F -- "${search}" | grep -vF -- "${FUNCNAME[0]}" | tail -n 1)
if [[ -z "${hist_info}" ]]; then
echo "${FUNCNAME[0]}: "${search}" not found." >&2
return 1
fi
local re='^[ t]*([0-9]+)[ t]+(.+)$'
local hist_num hist_cmd
hist_num=$(sed -E "s/${re}/1/" <<< "${hist_info}")
hist_cmd=$(sed -E "s/${re}/2/" <<< "${hist_info}")
history -d "${hist_num}"
if (( delete )); then
echo "Removed: ${hist_cmd}"
return 0
fi
local cmd="${hist_cmd/${search}/${replacement}}"
echo "${cmd}"
# Add the new command to the history.
history -s ${cmd}
eval ${cmd}
}
So now I can run historysub TYPO CORRECTION
to re-execute a command with a correction. It's not as good as being able to interactively edit the old command, but I think it should be good enough for my needs.
HSTR seemed appealing but turned out to be a bit too heavyweight for my taste.
I instead wrote my own bash function:
# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
# historysub SEARCH [REPLACEMENT]
# historysub -d SEARCH
#
# REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
# -d removes the last command matching SEARCH from the history without
# executing a new command.
historysub()
{
local delete=0
local usage=0
local OPTIND=1
while getopts ":hd" option; do
case "${option}" in
d) delete=1 ;;
h) usage=1 ;;
?) usage=2 ;;
esac
done
shift $((OPTIND - 1))
local search="${1}"
local replacement="${2}"
usage_text=
usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]n"
usage_text+=" ${FUNCNAME[0]} -d SEARCHn"
if (( usage )); then
echo -e "${usage_text}"
return $(( usage - 1 ))
fi
if [[ -z "${search}" ]]; then
echo -e "${usage_text}" >&2
return 1
fi
# Find the last matching history entry (excluding ourself).
local hist_info
hist_info=$(HISTTIMEFORMAT="" history | grep -F -- "${search}" | grep -vF -- "${FUNCNAME[0]}" | tail -n 1)
if [[ -z "${hist_info}" ]]; then
echo "${FUNCNAME[0]}: "${search}" not found." >&2
return 1
fi
local re='^[ t]*([0-9]+)[ t]+(.+)$'
local hist_num hist_cmd
hist_num=$(sed -E "s/${re}/1/" <<< "${hist_info}")
hist_cmd=$(sed -E "s/${re}/2/" <<< "${hist_info}")
history -d "${hist_num}"
if (( delete )); then
echo "Removed: ${hist_cmd}"
return 0
fi
local cmd="${hist_cmd/${search}/${replacement}}"
echo "${cmd}"
# Add the new command to the history.
history -s ${cmd}
eval ${cmd}
}
So now I can run historysub TYPO CORRECTION
to re-execute a command with a correction. It's not as good as being able to interactively edit the old command, but I think it should be good enough for my needs.
edited Feb 22 at 23:06
answered Oct 6 '18 at 19:20
jamesdlinjamesdlin
554413
554413
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- 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%2funix.stackexchange.com%2fquestions%2f456671%2fhow-can-i-permanently-correct-a-typo-in-my-last-bash-command%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
Possible duplicate of How to remove a single line from history?
– Ipor Sircer
Jul 17 '18 at 2:46
I already stated that I know how to remove a single history line, but by itself those mechanisms (
history -d
or editing.bash_history
in an editor) are too inconvenient to use. I'm specifically asking for more convenient approaches, particularly in the context of correcting an existing line (which might not entail complete removal of the original).– jamesdlin
Jul 17 '18 at 2:59
If bash doesn't support replacing lines, then you have to write this feature yourself. The good news: bash is opensource.
– Ipor Sircer
Jul 17 '18 at 3:05
@IporSircer I'm asking if bash supports replacing lines. Clearly it has some mechanism for doing so since there are a lot of questions asking how to prevent that from happening. Is it unreasonable to ask if there's a way to harness that power for good instead of evil?
– jamesdlin
Jul 17 '18 at 3:07
Read the fine manual (
man bash
); all features are documented. There are no hidden secrets.– Ipor Sircer
Jul 17 '18 at 3:08