2009-08-04 322 views
11

[編輯插入:同樣的海報的earlier question的可能的複製?]bash的grep的換行符

嗨,我需要從文件中提取:使用grep命令

first 
second 
third 

,下面一行:

second 
third 

grep命令應該怎麼樣?

+0

你的意思是說,這是字面意思還是你的意思是你想要第二和第三行,無論他們有什麼內容?另外,這是你的功課嗎? – Telemachus 2009-08-04 15:46:19

+0

不是我的功課,只是一項任務。我不知道如何在這裏構建正則表達式。 – Markus 2009-08-04 15:53:09

+1

我想要的是構造一個包含換行符的正則表達式。 – Markus 2009-08-04 15:53:50

回答

1

線?或線?

嘗試

grep -E -e '(second|third)' filename 

編輯: grep的是面向行的。你將不得不使用Perl,sed或awk來跨線執行模式匹配。

BTW -E告訴grep正則表達式是擴展RE。

0
grep -E '(second|third)' /path/to/file 
egrep -w 'second|third' /path/to/file 
2

我真的不明白你想要匹配什麼。我不會用grep,但下列之一:

tail -2 file   # to get last two lines 
head -n +2 file  # to get all but first line 
sed -e '2,3p;d' file # to get lines from second to third 

(不知道它是多麼的標準,它工作在GNU工具肯定)

8

你的問題抽象「的bash的grep換行」,意味着你會想匹配second\nthird字符序列 - 即包含換行符的東西。

由於grep對「行」起作用,而這兩行是不同的行,所以您無法以這種方式匹配它。

所以,我想它分成幾個任務:

  1. 你匹配的是包含「第二」的行並輸出了配線和後續行:

    grep -A 1 "second" testfile 
    
  2. 您將每隔一行換行轉換爲保證不會在輸入中出現的序列。我認爲,最簡單的辦法做到這一點會用perl:

    perl -npe '$x=1-$x; s/\n/##UnUsedSequence##/ if $x;' 
    
  3. 你做這些線的grep,這次爲字符串##UnUsedSequence##third搜索:

    grep "##UnUsedSequence##third" 
    
  4. 你解開未使用的序列回入新行,SED可能是最簡單的:

    sed -e 's/##UnUsedSequence##/\n' 
    

所以由此產生的管道命令做你想做的將看起來像:

grep -A 1 "second" testfile | perl -npe '$x=1-$x; s/\n/##UnUsedSequence##/ if $x;' | grep "##UnUsedSequence##third" | sed -e 's/##UnUsedSequence##/\n/' 

不是最優雅的,但應該工作。我很想知道更好的方法,但應該有一些。

1

所以你只是不想要包含「第一」的行? -v反轉grep結果。

$ echo -e "first\nsecond\nthird\n" | grep -v first 
second 
third 
3

我不認爲的grep是走在這條路上。

如果你只是想從任何文件中刪除第一行(以概括你的問題),我會使用sed來代替。

sed '1d' INPUT_FILE_NAME 

這會將文件的內容發送到第一行刪除的標準輸出。

然後,您可以將標準輸出重定向到另一個文件以捕獲結果。

sed '1d' INPUT_FILE_NAME > OUTPUT_FILE_NAME 

這應該做到這一點。

如果你必須使用的grep,只是不希望顯示與上第一行了,那就試試這個:

grep -v first INPUT_FILE_NAME 

通過傳遞-v開關,告訴grep向您展示一切,但您傳遞的表達式。實際上,除了其中的第一個的行外,其他行都會顯示。

但是,缺點是多個第一個在其中的文件不會顯示其他行,也可能不是您期望的行爲。

分流的結果到一個新文件,試試這個:

grep -v first INPUT_FILE_NAME > OUTPUT_FILE_NAME 

希望這有助於。

20

相反的grep,您可以使用pcregrep支持多模式

pcregrep -M 'second\nthird' file 

-M允許模式匹配超過一行。

0

你可以使用

$ grep -1 third filename 

這之前和之後打印帶有匹配和一個字符串的字符串。由於「third」在最後一個字符串中,因此您會得到最後兩個字符串。

0

我喜歡notnoop's answer,但AndrewY's answer建築(這是爲那些沒有pcregrep好,但太複雜),你可以做:

RESULT=`grep -A1 -s -m1 '^\s*second\s*$' file | grep -s -B1 -m1 '^\s*third\s*$'` 
0
grep -v '^first' filename 

凡-v標誌反轉匹配。

1

grep -A1「second」| grep -B1「third」很好地工作,如果你有多個匹配,它甚至會擺脫原來的匹配分隔符