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 &. >>> >>> >>>