
我發現這個有趣的命令:
grep -v '^>' test.fasta | tr -d '\n' | sed -e 's/\(.\)/\1\n/g' | sort | uniq -c | sort -rn
我對它的含義有所了解(它計算文本文件中的字母),但我的問題是這樣的:
sed -e 's/\(.\)/\1\n/g'
我知道它由三個替代命令組成。一種是替換換行符(\n
),即匹配除換行符(\(.\)
)之外的任何字符,但我迷失了/\1\
?
答案1
命令
sed -e 's/\(.\)/\1\n/g'
是一個 GNUsed
替換命令,它將每個字元替換為自身,後面跟著換行符。這樣做的效果是將輸入折疊成單一字元的單列。
$ echo hello | sed -e 's/\(.\)/\1\n/g'
h
e
l
l
o
這\(.\)
是一個“捕獲組”,捕獲單個字元。這\1
是對第一個捕獲組的“反向引用”。\1
在替換文字中使用將插入第一個括號捕獲的任何內容。
它也可以寫成沒有那麼多反斜杠,例如
sed 's/./&\n/g'
其中&
僅表示“表達式匹配的任何內容”。
該sed
指令要求 GNUsed
作為標準,sed
不能\n
像這樣插入換行符。
若要使用標準工具更有效地完成此操作,請使用
fold -w 1
反而。這更有效,因為輸入中的每個字元不需要正規表示式匹配。
使用fold
,您的管道可以編寫
grep -v '^>' file | tr -d '\n' | fold -w 1 | sort | uniq -c | sort -rn
或者,使用awk
來擺脫該管道的幾個步驟,
awk '!/^>/ { for (i = 1; i <= length; ++i) count[substr($0,i,1)]++ }
END { for (ch in count) print count[ch], ch }' file |
sort -rn
程式awk
碼計算每個字元出現的次數。它透過遞增count
與輸入流中的每個字元對應的數組中的值來實現這一點。輸入結束時,輸出計數和字元計數的摘要。
答案2
我希望這能讓事情變得更清楚。
“我知道它是由三個替代命令組成的”
這只是一個替代命令(如果您指的是該sed
命令):,s/<pattern to search>/<replacement>/
它將執行以下命令:
- 對於每一行搜尋
<pattern>
並將其替換為<replacement>
。 - 國旗
g
的意思是做吧G全局性的,因為預設情況下sed
僅替換第一次出現的<pattern>
.
“但我迷失了
/\1\
”
\(<pattern>\)
您可以透過使用轉義括號或僅使用選項括起來來捕獲模式-E
。(<pattern>)
在本<replacement>
節中,捕獲的模式由反斜線和數字 引用\<number>
。該數字指的是捕獲的位置,因為您可以有多個:
sed -E '/(<first capture>)(<second capture>)/\1\2/'
所以該指令的sed -e 's/\(.\)/\1\n/g'
意思是:
- 捕獲每個字元
\(.\)
並用其自身和新行替換它\1\n
。 - 使用
g
,全域執行,不要在第一次出現時停止。
例如:
$ echo foo | sed -E 's/(.)/\1\n/g'
f
o
o
-e
此處不需要這些選項,除非您要連接多個sed
命令:sed -e '...' -e '...'
等。
您可以在以下位置找到更多資訊:反向引用和子表達式。
答案3
使用 Raku(以前稱為 Perl_6)
raku -e 'for lines.grep({ !/ ^ \> / }).join { .say for .comb.Bag.sort(*.values).reverse};'
輸入範例:
>sp|P01308|INS_HUMAN Insulin OS=Homo sapiens OX=9606 GN=INS PE=1 SV=1
MALWMRLLPLLALLALWGPDPAAAFVNQHLCGSHLVEALYLVCGERGFFYTPKTRREAED
LQVGQVELGGGPGAGSLQPLALEGSLQKRGIVEQCCTSICSLYQLENYCN
範例輸出:
L => 20
G => 12
A => 10
E => 8
Q => 7
P => 6
C => 6
V => 6
R => 5
S => 5
Y => 4
F => 3
T => 3
N => 3
M => 2
D => 2
K => 2
I => 2
W => 2
H => 2
您提供的程式碼可以用多種語言(不僅僅是sed
)編寫,其中任何一種都可能引起您的共鳴。例如,上面的程式碼已用 Raku(Perl 語言家族的成員)重新編寫。
大多數 Raku 程式碼應該是相當不言自明的:lines
讀入,並grep
-ped 表示!
缺少^
行首>
「大於」角度,且join
-ed。連接的行是comb
-ed (分成單獨的字元),Bag
-ged (每個出現的字元變成 akey
並且出現次數被計數/記錄為values
),sort
-ed inreverse
首先放置最高的出現次數,然後用 列印say
。