Regarding the & word modifier, it would be useful to note in the documentation that it applies the previous substitution whether it had been successful or not, as shown below.
[root@localhost ~]# echo a a [root@localhost ~]# !:s/a/z/ echo z z [root@localhost ~]# echo a1 a1 [root@localhost ~]# !:& echo z1 z1 [root@localhost ~]# echo a2 a2 [root@localhost ~]# !:s/b/y/ bash: :s/b/y/: substitution failed [root@localhost ~]# echo b2 b2 [root@localhost ~]# !:& echo y2 y2 [root@localhost ~]# Jim On Tue, Nov 5, 2019 at 11:44 AM Jim Monte <jim.mont...@gmail.com> wrote: > The availability of the % string only after a command unrelated to it (not > using !??) is executed as shown below is not documented, but it probably > falls under the category of a bug. That is, it seems reasonable that both > echo "!%" commands should behave as the second one does. > [root@localhost ~]# bash > [root@localhost ~]# echo "!%" > bash: !: event not found > [root@localhost ~]# echo a >/dev/nul > [root@localhost ~]# echo "!%" > echo "" > > [root@localhost ~]# > > Jim > > On Mon, Nov 4, 2019 at 9:42 AM Jim Monte <jim.mont...@gmail.com> wrote: > >> Related to the issues with the ? event designator, the %word designator >> substitutes the *first* word matched by the ? event designator or nothing >> if the match begins with a space. These details are not documented. >> >> [root@localhost ~]# echo a b c d >/dev/nul >> [root@localhost ~]# echo !?b c? >> echo echo a b c d >/dev/nul >> [root@localhost ~]# echo "!%" >> echo "b" >> b >> [root@localhost ~]# echo a1 >/dev/nul >> [root@localhost ~]# echo !? a? >> echo echo a1 >/dev/nul >> [root@localhost ~]# echo "!%" >> echo "" >> >> Jim >> >> >> >> >> >> On Sun, Nov 3, 2019 at 9:18 AM Jim Monte <jim.mont...@gmail.com> wrote: >> >>> Two more documentation issues I have found are below. >>> >>> It appears that an empty substring event designator uses the string of >>> the previous substring event designator if none is provided and does not >>> find the event if there is no previous string. >>> >>> [root@localhost ~]# ls >>> dos hello.c >>> [root@localhost ~]# cat hello.c > /dev/nul >>> [root@localhost ~]# echo !?s? >>> echo ls >>> ls >>> [root@localhost ~]# echo !?? >>> echo echo ls >>> echo ls >>> [root@localhost ~]# ls -al > /dev/nul >>> [root@localhost ~]# echo !?? >>> echo ls -al > /dev/nul >>> [root@localhost ~]# echo s >>> s >>> [root@localhost ~]# echo !?? >>> echo echo s >>> echo s >>> [root@localhost ~]# echo !?l? >>> echo echo ls -al > /dev/nul >>> [root@localhost ~]# echo !?? >>> echo echo echo ls -al > /dev/nul >>> >>> [root@localhost ~]# bash >>> [root@localhost ~]# echo !?? >>> bash: !??: event not found >>> >>> This action is not documented. >>> >>> >>> >>> >>> >>> An empty "old" string in a substitute word modifier uses the previous >>> "old" if none is given, but uses an empty string if new is empty. If there >>> was no previous "old" string, an error is reported. >>> >>> [root@localhost ~]# echo f g i >>> f g i >>> [root@localhost ~]# echo !:s/g/k/ >>> echo echo f k i >>> echo f k i >>> [root@localhost ~]# echo af ag ai >>> af ag ai >>> [root@localhost ~]# echo !:s/// >>> echo echo af a ai >>> echo af a ai >>> [root@localhost ~]# echo bf bg bi >>> bf bg bi >>> [root@localhost ~]# echo !:s//1/ >>> echo echo bf b1 bi >>> echo bf b1 bi >>> [root@localhost ~]# echo gf gg gi >>> gf gg gi >>> [root@localhost ~]# echo !:gs//2/ >>> echo echo 2f 22 2i >>> echo 2f 22 2i >>> >>> [root@localhost ~]# bash >>> [root@localhost ~]# echo a b c >>> a b c >>> [root@localhost ~]# echo !:s//1/ >>> bash: :s//1/: no previous substitution >>> >>> Again, this behavior is not documented. >>> >>> On Thu, Oct 10, 2019 at 10:35 PM Jim Monte <jim.mont...@gmail.com> >>> wrote: >>> >>>> Hi, >>>> >>>> This bug report has been my first one for Bash. I have not found how to >>>> check the status of the bug. Would you please provide this information? >>>> >>>> Below are a couple more issues I found. >>>> >>>> There is an inconsistency with the documentation and behavior of the ^ >>>> word designator. According to documentation, it refers to the first >>>> argument but does not require a ':' before it if it starts the word >>>> designator. However, it does not act like the numerical word designator 1 >>>> at the end of a range. >>>> >>>> [root@localhost ~]# echo a b c >>>> a b c >>>> [root@localhost ~]# echo !!:1-1 >>>> echo a >>>> a >>>> [root@localhost ~]# echo a b c >>>> a b c >>>> [root@localhost ~]# echo !!:^-^ >>>> echo a b^ >>>> a b^ >>>> >>>> Also it is not explicitly documented that :- is equivalent to :0- >>>> >>>> [root@localhost ~]# echo a b c d >>>> a b c d >>>> [root@localhost ~]# echo !!:- >>>> echo echo a b c >>>> echo a b c >>>> [root@localhost ~]# echo a b c d >>>> a b c d >>>> [root@localhost ~]# echo !!:0- >>>> echo echo a b c >>>> echo a b c >>>> >>>> >>>> Jim Monte >>>> >>>> On Thu, Oct 3, 2019 at 6:19 PM Jim Monte <jim.mont...@gmail.com> wrote: >>>> >>>>> Hi All, >>>>> >>>>> Below are some issues I found with history substitution. I am >>>>> duplicating its behavior in a somewhat different use, and found issues >>>>> with >>>>> the documentation and bugs as described. >>>>> >>>>> Jim Monte >>>>> >>>>> >>>>> >>>>> >>>>> From: jim >>>>> To: bug-bash@gnu.org >>>>> Subject: Issues with history substitution and its documentation >>>>> >>>>> Configuration Information [Automatically generated, do not change]: >>>>> Machine: x86_64 >>>>> OS: linux-gnu >>>>> Compiler: gcc >>>>> Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' >>>>> -DCONF_OSTYPE='l$ >>>>> uname output: Linux T5500-Ubuntu 4.18.0-22-generic #23~18.04.1-Ubuntu >>>>> SMP Thu J$ >>>>> Machine Type: x86_64-pc-linux-gnu >>>>> >>>>> Bash Version: 4.4 >>>>> Patch Level: 19 >>>>> Release Status: release >>>>> >>>>> Description: >>>>> >>>>> ============================================================================= >>>>> Documentation of quick substitution is incorrect (or does not match >>>>> behavior). >>>>> >>>>> I believe this issue is an error with the documentation of history >>>>> "Quick Substitution" that has existed since the first snapshot >>>>> available at >>>>> web.archive.org in 2007 at >>>>> >>>>> >>>>> https://web.archive.org/web/20071223174140/http://www.gnu.org/software/bash/manual/html_node/Event-Designators.html >>>>> >>>>> At the least it is true that bash does not behave as the documentation >>>>> states, >>>>> but it does act in a way that is more reasonable (to me) than what is >>>>> written. >>>>> >>>>> The documentation states that ^string1^string2^ is equivalent to >>>>> !!:s/string1/string2/. However, bash treats it as equivalent to >>>>> !!:s^string1^string2^. >>>>> >>>>> jim@T5500-Ubuntu:~$ echo /a >>>>> /a >>>>> jim@T5500-Ubuntu:~$ ^/a^b^ >>>>> echo b >>>>> b >>>>> jim@T5500-Ubuntu:~$ echo /a >>>>> /a >>>>> jim@T5500-Ubuntu:~$ !!:s//a/b/ >>>>> echo ab/ >>>>> ab/ >>>>> jim@T5500-Ubuntu:~$ echo /a >>>>> /a >>>>> jim@T5500-Ubuntu:~$ !!:s^/a^b^ >>>>> echo b >>>>> b >>>>> >>>>> >>>>> ============================================================================= >>>>> Behavior of empty "old" string in a substitution is undefined. >>>>> >>>>> The earlier example also shows a related but different issue with the >>>>> !!:s//a/b/ command, where the string to locate is empty. >>>>> It causes /a to be replaced by a and the b/ is appended. >>>>> >>>>> But >>>>> jim@T5500-Ubuntu:~$ echo ///a >>>>> ///a >>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>> echo //z >>>>> //z >>>>> >>>>> Here the empty string caused /a to be replaced by z. >>>>> >>>>> However, >>>>> jim@T5500-Ubuntu:~$ echo ///abcdefg >>>>> ///abcdefg >>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>> echo //zbcdefg >>>>> //zbcdefg >>>>> >>>>> Here a slash and the first character of the second word are replaced >>>>> by z. >>>>> >>>>> >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>> echo z b c >>>>> z b c >>>>> >>>>> >>>>> jim@T5500-Ubuntu:~$ echo /// >>>>> /// >>>>> jim@T5500-Ubuntu:~$ !!:s//z/ >>>>> bash: :s//z/: substitution failed >>>>> >>>>> Using :gs instead of :s does not change the results. >>>>> >>>>> >>>>> ============================================================================= >>>>> BUG >>>>> If an event designator has a leading - character, it is ignored. >>>>> >>>>> jim@T5500-Ubuntu:~/tmp$ cat main.c >>>>> #include <stdio.h> >>>>> int main(void) >>>>> { >>>>> (void) fprintf(stdout, "Hello, world!\n"); >>>>> return 0; >>>>> } >>>>> >>>>> jim@T5500-Ubuntu:~/tmp$ gcc main.c -o"-a" >>>>> jim@T5500-Ubuntu:~/tmp$ gcc main.c -o"-b" >>>>> jim@T5500-Ubuntu:~/tmp$ -a >>>>> Hello, world! >>>>> jim@T5500-Ubuntu:~/tmp$ !-a:s/a/b >>>>> bpt-cache abc >>>>> >>>>> >>>>> >>>>> ============================================================================= >>>>> Documentation of the :h and :t modifiers in section 9.3.3 is >>>>> incomplete. >>>>> :h removes the last / and everything after it if a / is present. >>>>> Otherwise >>>>> it does nothing. >>>>> >>>>> :t removes everything before and including the last / if one is >>>>> present. >>>>> Otherwise it does nothing. >>>>> >>>>> If a slash is present, !!:h/!!:t is equivalent to !!. >>>>> >>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>> /a/b/c/d >>>>> jim@T5500-Ubuntu:~$ !!:h >>>>> echo /a/b/c >>>>> /a/b/c >>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>> /a/b/c/d >>>>> jim@T5500-Ubuntu:~$ !!:h:h >>>>> echo /a/b >>>>> /a/b >>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>> /a/b/c/d >>>>> jim@T5500-Ubuntu:~$ !!:h:h:h >>>>> echo /a >>>>> /a >>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>> /a/b/c/d >>>>> jim@T5500-Ubuntu:~$ !!:h:h:h:h >>>>> echo >>>>> >>>>> jim@T5500-Ubuntu:~$ >>>>> jim@T5500-Ubuntu:~$ echo /a/b/c/d >>>>> /a/b/c/d >>>>> jim@T5500-Ubuntu:~$ !!:t >>>>> d >>>>> d: command not found >>>>> >>>>> >>>>> jim@T5500-Ubuntu:~$ echo a/b >>>>> a/b >>>>> jim@T5500-Ubuntu:~$ !!:h/!!:t >>>>> echo a/b >>>>> a/b >>>>> jim@T5500-Ubuntu:~$ echo a/b >>>>> a/b >>>>> jim@T5500-Ubuntu:~$ !! >>>>> echo a/b >>>>> a/b >>>>> >>>>> >>>>> >>>>> ============================================================================= >>>>> Documentation of the :r and :e modifiers is incomplete. >>>>> :r removes the last ".suffix" and everything after it, if a ".suffix" >>>>> is >>>>> present. Otherwise it does nothing. >>>>> :e leaves the last ".suffix" and everything after it, if a ".suffix" is >>>>> present. Otherwise it does nothing. >>>>> >>>>> jim@T5500-Ubuntu:~$ echo .suffix a b .suffix c d >>>>> .suffix a b .suffix c d >>>>> jim@T5500-Ubuntu:~$ !!:r >>>>> echo .suffix a b >>>>> .suffix a b >>>>> jim@T5500-Ubuntu:~$ echo .suffix a b .suffix c d >>>>> .suffix a b .suffix c d >>>>> jim@T5500-Ubuntu:~$ !!:r:r >>>>> echo >>>>> >>>>> jim@T5500-Ubuntu:~$ echo .suffix a b .suffix c d >>>>> .suffix a b .suffix c d >>>>> jim@T5500-Ubuntu:~$ !!:e >>>>> .suffix c d >>>>> >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:r >>>>> echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:e >>>>> echo a b c >>>>> a b c >>>>> >>>>> >>>>> ============================================================================= >>>>> BUG >>>>> :p does not suppress execution if it is duplicated. >>>>> >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:p >>>>> echo a b c >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:p:p >>>>> echo a b c >>>>> a b c >>>>> >>>>> >>>>> ============================================================================= >>>>> Documentation of :q and :x is incomplete. >>>>> If :q and :x are repeated, the last specification is taken. >>>>> >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:q >>>>> 'echo a b c' >>>>> echo a b c: command not found >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:x >>>>> 'echo' 'a' 'b' 'c' >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:q:x >>>>> 'echo' 'a' 'b' 'c' >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:q:x:q >>>>> 'echo a b c' >>>>> echo a b c: command not found >>>>> jim@T5500-Ubuntu:~$ echo a b c >>>>> a b c >>>>> jim@T5500-Ubuntu:~$ !!:q:x:q:x >>>>> 'echo' 'a' 'b' 'c' >>>>> a b c >>>>> >>>>> >>>>> >>>>> ============================================================================= >>>>> Finally, documentation of G should mention that it can be used with >>>>> both :s and &. >>>>> >>>>> >>>>>