sed命令的解釋

sed命令的解釋

我發現這個有趣的命令:

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

https://raku.org

相關內容