2012-03-24 36 views
3

我想使用sed(1)从字符串中删除括号,但仅当括号以特定字符串开头时。例如,我想将一个字符串(如Song Name (f/ featured artist) (Remix))更改为Song Name f/ featuredartist (Remix)。我怎样才能做到这一点?使用sed去除字符串中的括号

我目前正在执行以下操作:

echo "Song Name (f/ featuredartist) (Remix)" | sed s/"(f\/ [a-z]*)"/"f\/ "/ 

但所有这样做是返回Song Name f/ (Remix)

另请注意:f/)之间的任何内容,而不仅仅是[a-z]*,因为我的工作尝试意味着。

+0

您需要使用捕捉组(工作不知道他们是在SED可用,找一找向上)。 – SJuan76 2012-03-24 20:59:00

+1

什么都可以?是这样吗?哇(f /(/ f嵌套)特色艺术家)。这属于“任何事情”。哪一个是最后一个? – Kaz 2012-03-24 21:03:29

+0

@kaz在这种情况下的输出将是“f /(/ f嵌套)精华帖” – finiteloop 2012-03-24 21:09:50

回答

4

这可能会为你工作:

echo "Song Name (f/ featuredartist) (Remix)" | sed 's|(\(f/[^)]*\))|\1|' 
Song Name f/ featuredartist (Remix) 
+0

这就行了。谢谢!您介意sed命令中语法的快速解释吗?我有正则表达式的一般知识,但希望理解sed命令中\ 1的用法。 – finiteloop 2012-03-25 17:01:14

+0

请参阅[这里](http://www.grymoire.com/Unix/Sed.html#toc-uh-4)以获得解释(以及完整的教程)。 – potong 2012-03-25 18:26:23

1
echo 'Song Name (f/ featured artist) (Remix)' | sed 's/\(.*\)(\(f\/[^)]\+\))/\1\2/' 
+0

我认为你正在尝试做一些类似于此处解释的内容:http://www.grymoire.com/Unix/Sed.html#uh-4但是,该特定行无法去掉括号。 – finiteloop 2012-03-24 21:11:22

+0

@segfault,这个有什么问题吗?它适用于示例 – perreal 2012-03-24 21:36:19

+0

您在响应中给出的行甚至在我的shell中尝试时也没有工作 – finiteloop 2012-03-25 17:01:05

0

TXR解决方案(http://www.nongnu.org/txr)。

@;; a texts is a collection of text pieces 
@;; with no gaps in between. 
@;; 
@(define texts (out))@\ 
    @(coll :gap 0)@(textpiece out)@(end)@\ 
    @(cat out "")@\ 
@(end) 
@;; 
@;; recursion depth indicator 
@;; 
@(bind recur 0) 
@;; 
@;; a textpiece is a paren unit, 
@;; or a sequence of chars other than parens. 
@;; or, else, in the non-recursive case only, 
@;; any character. 
@;; 
@(define textpiece (out))@\ 
    @(cases)@\ 
    @(paren out)@\ 
    @(or)@\ 
    @{out /[^()]+/}@\ 
    @(or)@\ 
    @(bind recur 0)@\ 
    @{out /./}@\ 
    @(end)@\ 
@(end) 
@;; 
@;; a paren unit consists 
@;; of (followed by a space-delimited token 
@;; followed by some texts (in recursive mode) 
@;; followed by a closing paren). 
@;; Based on what the word is, we transform 
@;; the text. 
@;; 
@(define paren (out))@\ 
    @(local word inner level)@\ 
    @(bind level recur)@\ 
    @(local recur)@\ 
    @(bind recur @(+ level 1))@\ 
    (@word @(texts inner))@\ 
    @(cases)@\ 
    @(bind recur 1)@\ 
    @(bind word ("f/") ;; extend list here 
      )@\ 
    @(bind out inner)@\ 
    @(or)@\ 
    @(bind out `(@word @inner)`)@\ 
    @(end)@\ 
@(end) 
@;; scan standard input in freeform (as one big line) 
@(freeform) 
@(texts out)@trailjunk 
@(output) 
@[email protected] 
@(end) 

采样运行:

$ txr paren.txr - 
a b c d 
[Ctrl-D] 
a b c d 

$ txr paren.txr - 
The quick brown (f/ ox jumped over the (f/ lazy) dogs). (
The quick brown ox jumped over the (f/ lazy) dogs. (
+0

“recur”变量是一个动态范围的黑客行为。 'texts'模式函数只能识别非嵌套情况下的任意单个字符,否则它会吃掉右括号。在'paren'中,我们使用嵌套层次来在第一递归级别出现'f /'时仅去掉括号。但是,无论如何,我们都认识到括号嵌套。 – Kaz 2012-03-24 22:22:34

+0

这使得Perl和PCRE中的递归模式看起来很容易。 – tchrist 2012-03-25 00:53:27

+0

让我看看代码。 – Kaz 2012-03-25 03:43:25