[英]rename specific lines in a text file with sed
我有一個看起來像這樣的文件:
>alks|keep1|aoiuor|lskdjf
ldkfj
alksj
asdflkj
>jhoj_kl|keep2|kjghoij|adfjl
aldskj
alskj
alsdkj
我想只編輯以>
開頭的行,最好是就地編輯,以獲取文件:
>keep1
ldkfj
alksj
asdflkj
>keep2
aldskj
alskj
alsdkj
我知道原則上這可以通過 sed/awk/cut 的各種組合來實現,但我一直無法找出正確的組合。 理想情況下它應該很快——文件有數百萬行,而且許多行也很長。
關於我要編輯的行的關鍵內容:
>
開頭|
(因此思考cut
會有所幫助(我的大多數 sed 嘗試都是純垃圾)
cut -d '|' -f 2 test.txt
得到我想要的字符串,它也保留其他行。 所以它很接近,但是(當然)它不會在cut
應用的行上保留初始>
,因此它缺少解決方案的關鍵部分。
使用sed
:
sed -E '/^>/ s/^[^|]+\|([^|]+).*/>\1/'
/^>/
到 select 以>
開頭的行,對於給定的樣本不是絕對必要的,但有時這比單獨使用s
提供更快的結果^[^|]+\|
這將匹配非|
從行首開始的字符([^|]+)
捕獲第二個字段.*
rest 的線>\1
替換字符串,其中\1
將具有([^|]+)
的內容如果您的輸入只有 ASCII 字符,這將為您提供更快的結果:
LC_ALL=C sed -E '/^>/ s/^[^|]+\|([^|]+).*/>\1/'
定時
awk
更快,而mawk
甚至更快sed
解決方案對於實際數據更快使用您顯示的示例,您可以簡單地嘗試以下操作。 在此代碼中,我們將字段分隔符設置為|
對於 Input_file 的所有行,然后在主程序中檢查行是否從>
開始,然后打印第二個字段,否則打印完整的行。
awk -F'|' '/^>/{print ">"$2;next} 1' Input_file
說明:為上述添加詳細說明。
awk -F'|' ' ##Starting awk program from here and setting field separator as | here.
/^>/{ ##Checking condition if line starts from > then do following.
print ">"$2 ##Printing 2nd field of current line here.
next ##next will skip all further statements from here.
}
1 ##Will print current line.
' Input_file ##mentioning Input_file name here.
您還可以使用以下awk
命令:
awk -F\| '/^>/{print ">"$2} !/^>/{print}' file
# Inplace replacement with gawk (GNU awk)
gawk -i inplace -F\| '/^>/{print ">"$2} !/^>/{print}' file
# "Inline-like" replacement with any awk
awk -F\| '/^>/{print ">"$2} !/^>/{print}' file > tmp && mv tmp file
這里,
-F\|
- 將字段分隔符設置為|
字符/^>/
是條件:如果行以<
開頭(而!/^>/
表示相反){print ">"$2}
打印字段 2 的值,並在其前面加上>
字符{print}
只是打印整行。 請注意,由於!/^>/{print}
可以簡化為!/^>/
因為print
是默認操作。
查看在線演示:
s='>alks|keep1|aoiuor|lskdjf
ldkfj
alksj
asdflkj
>jhoj_kl|keep2|kjghoij|adfjl
aldskj
alskj
alsdkj'
awk -F\| '/^>/{print ">"$2} !/^>/{print}' <<< "$s"
Output:
>keep1
ldkfj
alksj
asdflkj
>keep2
aldskj
alskj
alsdkj
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.