如何匹配bash历史扩展中的行尾

时间:2014-04-24 10:26:40

标签: bash

Bash为历史扩展提供了很好的支持,例如:

echo onetwoone
echo !$
=> onetwoone

此外,我们可以根据man bash使用替换:

echo onetwoone
echo !$:s/one/three/
=> threetwoone

首先,我认为这与sed的语法类似,但事实并非如此。我找不到匹配字符串后端的方法。

echo onetwoone | sed 's/one$/three/'
=> onetwothree

我想对bash的历史扩展做同样的事情:

echo onetwoone
echo !$:s/one$/three/
=> -bash: :s/one$/three/: substitution failed

有没有办法实现这一目标?谢谢!

2 个答案:

答案 0 :(得分:2)

似乎s修饰符不理解正则表达式。

解决方法可能是使用sed

$ echo onetwoone
onetwoone

使用sed

$ sed 's/one$/three/' <<< $(echo !$)
sed 's/one$/three/' <<< $(echo onetwoone)
onetwothree

您可能还想引用fc,这样您就可以从history中选择一个命令并在编辑器中打开它(基于$EDITOR),您可以在其中执行所需的操作操作:

   fc [-e ename] [-lnr] [first] [last]
   fc -s [pat=rep] [cmd]
          Fix Command.  In the first form, a range of commands from  first
          to  last  is selected from the history list.  First and last may
          be specified as a string (to locate the last  command  beginning
          with  that  string)  or  as  a number (an index into the history
          list, where a negative number is used as an offset from the cur‐
          rent command number).  If last is not specified it is set to the
          current command for listing (so that ``fc -l  -10''  prints  the
          last 10 commands) and to first otherwise.  If first is not spec‐
          ified it is set to the previous command for editing and -16  for
          listing.

          The  -n option suppresses the command numbers when listing.  The
          -r option reverses the order of the commands.  If the -l  option
          is  given,  the  commands are listed on standard output.  Other‐
          wise, the editor given by ename is invoked on a file  containing
          those  commands.  If ename is not given, the value of the FCEDIT
          variable is used, and the value of EDITOR if FCEDIT is not  set.
          If  neither  variable  is set, vi is used.  When editing is com‐
          plete, the edited commands are echoed and executed.

          In the second form, command is re-executed after  each  instance
          of  pat  is replaced by rep.  A useful alias to use with this is
          ``r="fc -s"'', so that typing ``r cc''  runs  the  last  command
          beginning with ``cc'' and typing ``r'' re-executes the last com‐
          mand.

答案 1 :(得分:0)

我不这么认为。引自手册(https://www.gnu.org/software/bash/manual/bash.html#Modifiers

  

S /旧/新/

     
    

在事件行中第一次出现 old 替换 new 。可以使用任何分隔符代替'/'。可以使用单个反斜杠在 new 中引用分隔符。如果“&amp;”出现在 new 中,则会被替换。单个反斜杠将引用'&amp;'。如果最后一个分隔符是输入行的最后一个字符,则它是可选的。

  

关于是正则表达式或任何类型的模式,它没有说什么。

您可以做额外的工作:将“one”替换为“three”,重复替换,然后将第一个“three”替换为“one”

$ echo onetwoone
onetwoone
$ echo !$:s/one/three/:&:s/three/one
echo onetwothree
onetwothree