Text-Processing
從欄位中提取長度為 n 的數字並返回字元串
我有一個包含文本和數字組合的製表符分隔文件。我想保持每一行不變,但我只想保留第 5 列中的六位數字(如果存在)。例如:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
(以 Syndrome # 為例,它可以是任何文本,所以不是我可以搜尋和刪除的模式)
我希望輸出為:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source
我有 4 種方法來提取 6 位數字,但是,我不能
一種。輸出它起源的行中的數字
灣。使用一個已編輯的欄位成功列印整行。我用來提取數字的選項是:
cat inputfile | cut -f 5 |grep -P '(? < !\d)\d{6}(?!\d)' cat inputfile | cut -f 5 |grep -Po '(?< !\d)\d{6}(?!\d)' cat inputfile | cut -f 5 |grep -o '[[:digit:]]*' cat inputfile | cut -f 5 |grep -o "[0-9]\{6\}"
我知道對列使用 cut 是不正確的,但我想確保我的提取正確,因為欄位 9 中還有一個六位數。我一直堅持把這些放在一起。在此先感謝您的任何建議
如果我理解正確,您希望第 5 列成為其中所有 6 位數字的空格串聯。
也許:
perl -F'\t' -lape ' $F[4] = join " ", grep {length == 6} ($F[4] =~ /\d+/g); $_ = join "\t", @F' < file
或者重用您對運營商的負面看法:
perl -F'\t' -lape ' $F[4] = join " ", ($F[4] =~ /(?<!\d)\d{6}(?!\d)/g); $_ = join "\t", @F' < file
與
awk
:awk -F'\t' -v OFS='\t' ' { repl = sep = "" while (match($5, /[0-9]+/)) { if (RLENGTH == 6) { repl = repl sep substr($5, RSTART, RLENGTH) sep = " " } $5 = substr($5, RSTART+RLENGTH) } $5 = repl print }' < file
grep
本身不是很適合這項任務。grep
旨在列印與模式匹配的行。一些實現,如 GNU 或 ast-opengrep
,或者pcregrep
可以從匹配的行中提取字元串,但這非常有限。我能想到的唯一可以在一些限制下工作的
cut
++方法是實現grep
:paste``pcregrep
grep
n='(?:.*?((?1)))?' paste <(< file cut -f1-4) <(< file cut -f5 | pcregrep --om-separator=" " -o1 -o2 -o3 -o4 -o5 -o6 -o7 -o8 -o9 \ "((?<!\d)\d{6}(?!\d))$n$n$n$n$n$n$n$n" ) <(< file cut -f6-)
假設每行輸入至少有 6 個欄位,並且每個欄位的第 5 個欄位有 1 到 9 個 6 位數字。