帶循環的 Grep 重複模式
我有兩個文件:
文件1:
ABA FFR HHI HAB
文件2:
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
file1 中的每一行都是在 file2 中相應行的開頭重複的模式。我想從 file2 中獲取不是 file1 中重複模式的每一行的部分。
所需的輸出:
TRCFUJIKHRTHVFHJJHVHJJKKHGCC FHJKGHKKBVDTHJNJ DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII GTHFOOLLLHHHUUJCIICXXTKCIABAGGC
我嘗試使用這個循環:
while read -r line do grep -v "$line{1,}" file2.txt done < file1.txt
但我去這個輸出:
ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC ABAABAABAABAABAABAABAABAABATRCFUJIKHRTHVFHJJHVHJJKKHGCC FFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFFRFHJKGHKKBVDTHJNJ HHIHHIHHIHHIHHIDEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII HABHABHABHABHABHABHABHABGTHFOOLLLHHHUUJCIICXXTKCIABAGGC
使用 eg
ABA
在變數中,grep -v "$line{1,}"
會給 grep 模式ABA{1,}
,這意味著它會尋找一個 singleA
,一個 singleB
,然後至少一個A
。不過,最後一次重複並不重要,因為在那之後就什麼都沒有了,所以即使是一個重複也ABA
可以匹配。好吧,除了預設情況下,grep 使用基本正則表達式 (BRE),其中計數的重複必須用反斜杠書寫,如. 在擴展正則表達式 (ERE) 中,是否會有一個或多個重複(也會如此);但在 BRE 中,它只是四個文字字元(也是正常字元)。
\{*n*,*m*\}``{1,}``+``+
但是 grep 列印匹配或不匹配的完整行;
-v
它不會刪除部分行。(除了grep -o
它只列印匹配部分的地方,但我認為這不適用於-v
.)另外,使用該循環,grep
將查看每個模式的所有行,這就是為什麼你會得到file2
重複多次的內容.我們需要一個循環,在每次迭代時從每個輸入中讀取一行。它可以在shell中完成,但它會很慢。像 AWK 這樣的東西會更好,例如:
$ awk '{getline pat < "file1"; sub("^(" pat ")*", ""); print}' file2 TRCFUJIKHRTHVFHJJHVHJJKKHGCC FHJKGHKKBVDTHJNJ DEDRJFKOLGCUOUUKJGLNJKKKKJKJKJGGHHBCFDII GTHFOOLLLHHHUUJCIICXXTKCIABAGGC
AWK 程序隱式循環遍歷(和命令行上給出的其他文件)的行,在這裡,我們從每次迭代中
file2
顯式讀取一行。file1
然後"^(" pat ")*"
構造一個類似 的模式^(ABA)*
,它與目前行匹配,並用空字元串替換。這不會從行中刪除任何模式實例,例如
ABAABAFOOABABAR
會變成FOOABABAR
. 如果您也想刪除它們,請將其更改為gsub("(" pat ")*", "");
.