2012-03-24 38 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