最近我不得不编写一个在XenServer中解析虚拟机的小脚本,因为虚拟机的名称主要是在Windows XP或Windows Server 2008中使用空格,我不得不修剪这些空格并用下划线替换它们_.我找到了一个简单的解决方案,使用sed这是一个很好的工具,当涉及到字符串操作.
echo "This is just a test" | sed -e 's/ /_/g'
Run Code Online (Sandbox Code Playgroud)
回报
This_is_just_a_test
Run Code Online (Sandbox Code Playgroud) 我运行几个替换命令作为maven的colorize脚本的核心.其中的sed命令,使用正则表达式,在shell工作发现这里讨论.可以在此处找到当前(不工作)的实现.
当我将该命令的一个变体包含到脚本中时,会发生不同的行为:
变式1:
$ sed -re "s/([a-zA-Z0-9./\\ :-]+)/\1/g"
Run Code Online (Sandbox Code Playgroud)
适应脚本:
-re "s/WARNING: ([a-zA-Z0-9./\\ :-]+)/${warn}WARNING: \1${c_end}/g" \
Run Code Online (Sandbox Code Playgroud)
错误: shell输出的信息与我输入的信息相同$ sed.奇怪!?
变式2:
$ sed -e "s/\([a-zA-Z0-9./\\ :-]\+\)/\1/g"
Run Code Online (Sandbox Code Playgroud)
适应脚本:
-e "s/WARNING: \([a-zA-Z0-9./\\ :-]\+\)/${warn}WARNING: \1${c_end}/g" \
Run Code Online (Sandbox Code Playgroud)
错误:
sed:-e表达式#7,char 59:`s'命令的RHS上的引用\ 1无效
在Mac OS 10.10.3下,我通过输入以下命令安装了gnu-sed:
brew install gnu-sed --default-names
Run Code Online (Sandbox Code Playgroud)
当我再次输入时,我收到消息:
已经安装了gnu-sed-4.2.2
但是,即使重新启动系统并重新启动终端,我仍然无法使用sed的GNU版本.例如:
echo a | sed ’s_A_X_i’
Run Code Online (Sandbox Code Playgroud)
返回:替换命令'i'中的坏标志
我该怎么做才能让GNU版本正常工作?以下是$ PATH变量中的路径.
/Users/WN/-myUnix
/opt/local/bin
/opt/local/sbin
/usr/bin
/bin
/usr/sbin
/sbin
/usr/local/bin
/Applications/calibre.app/Contents/MacOS
/opt/ImageMagick/bin
/usr/texbin
Run Code Online (Sandbox Code Playgroud)
如果我的问题看起来很明显,我很抱歉,但我自己学习shell脚本,并且还不太了解UNIX程序的安装方式.任何帮助使用GNU兼容命令(在这种情况下sed,但很快我也需要其他人)在我的Mac上不会造成损害或不必要的混乱将非常感激.
我的示例字符串如下:
This is 02G05 a test string 20-Jul-2012
Run Code Online (Sandbox Code Playgroud)
现在从我想要提取的上面的字符串02G05.为此我用sed尝试了以下正则表达式
$ echo "This is 02G05 a test string 20-Jul-2012" | sed -n '/\d+G\d+/p'
Run Code Online (Sandbox Code Playgroud)
但上面的命令没有打印任何东西,我相信它的原因是它无法匹配我提供给sed的模式.
所以,我的问题是我在这里做错了什么以及如何纠正它.
当我用python尝试上面的字符串和模式时,我得到了我的结果
>>> re.findall(r'\d+G\d+',st)
['02G05']
>>>
Run Code Online (Sandbox Code Playgroud) 如何sed根据某个表达式创建过滤器匹配行,但忽略不匹配的行,而不是让它们打印?
作为一个真实的例子,我想scalac在一组文件上运行(Scala编译器),并从其-verbose输出中读取.class创建的文件.scalac -verbose输出一堆消息,但我们只对表单中的消息感兴趣[wrote some-class-name.class].我目前正在做的是这个(|&是bash 4.0将stderr传递给下一个程序的方法):
$ scalac -verbose some-file.scala ... |& sed 's/^\[wrote \(.*\.class\)\]$/\1/'
Run Code Online (Sandbox Code Playgroud)
这将从我们感兴趣的消息中提取文件名,但也会让所有其他消息保持不变!当然我们可以这样做:
$ scalac -verbose some-file.scala ... |& grep '^\[wrote .*\.class\]$' |
sed 's/^\[wrote \(.*\.class\)\]$/\1/'
Run Code Online (Sandbox Code Playgroud)
哪个有效,但看起来非常像绕过真正的问题,这是如何指示sed从输入中忽略不匹配的行.那我们该怎么做呢?
我使用下面的代码替换shell脚本中的字符串.
echo $LINE | sed -e 's/12345678/"$replace"/g'
Run Code Online (Sandbox Code Playgroud)
但它正在被替换$replace而不是该变量的值.
谁有人说出了什么问题?
我有一个看起来像这样的文件:
<table name="content_analyzer" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
<type="global" />
</table>
Run Code Online (Sandbox Code Playgroud)
我需要在后面的引号中提取任何内容name=,即content_analyzer,content_analyzer2和content_analyzer_items.
我在Linux机器上这样做,所以使用sed,perl,grep或bash的解决方案很好.
这是示例文件:
somestuff...
all: thing otherthing
some other stuff
Run Code Online (Sandbox Code Playgroud)
我想要做的是添加到以这样开头的行all::
somestuff...
all: thing otherthing anotherthing
some other stuff
Run Code Online (Sandbox Code Playgroud) 我想浏览一堆目录并将所有以_test.rb结尾的文件重命名为_spec.rb结尾.这是我从未想过如何处理bash的事情所以这次我认为我会付出一些努力来实现它.到目前为止,我做得很短,我最大的努力是:
find spec -name "*_test.rb" -exec echo mv {} `echo {} | sed s/test/spec/` \;
Run Code Online (Sandbox Code Playgroud)
注意:在exec之后有一个额外的回声,所以在我测试时打印命令而不是运行.
当我运行它时,每个匹配文件名的输出是:
mv original original
Run Code Online (Sandbox Code Playgroud)
即sed的替换已经丢失.有什么诀窍?
我在Linux命令行,我有文件
127.0.0.1
128.0.0.0
121.121.33.111
Run Code Online (Sandbox Code Playgroud)
我想要
127.0.0.1:80
128.0.0.0:80
121.121.33.111:80
Run Code Online (Sandbox Code Playgroud)
我记得我的同事们正在使用sed,但在阅读sed手册后仍然不清楚如何在命令行上执行此操作?