Text-Processing

刪除列中字元之前的所有內容

  • April 18, 2022

我有一張這樣的桌子

start end chr
 1   10  H300Chr01
 10  50  H500Chr02

我想替換 column3 中“Chr”之前的所有內容。

我想要的輸出是

start end chr
 1   10  Chr01
 10  50  Chr02

我知道sed可以做這樣的事情:

sed 's/^.*Chr/Chr/' table.txt

您能否告訴我如何為特定列或幾列實現這一目標?

對於特定列:

awk '{sub(/.*Chr/,"Chr",$3); print}' file

的第一個參數sub是要匹配的模式,第二個是替換,最後一個是目標。結果儲存到目標。另請參見awk 字元串函式

這可以擴展為更多列,例如:

awk '{sub(/.*Chr1/,"Chr1",$1); sub(/.*Chr2/,"Chr2",$2); print}' file

請注意,匹配是如預期的那樣貪婪,這是您的數據所需的行為。

要格式化輸出,它可能比定義OFS將輸出通過管道傳輸到更方便column -t,對於帶有實際空格的類似製表符的漂亮列印,沒有製表符。

對於一些(全部?)awk實現,當然是 GNUawkmawk我在 Arch Linux 系統上的實現,您可以將欄位分隔符設置為正則表達式,這使得 awk 保留文件的原始分隔符。為了顯示:

$ awk '{$1=$1;print}' file
start end chr
1 10 H300Chr01
10 50 H500Chr02

$ awk -F'[ ]' '{$1=$1;print}' file
start end chr
 1   10  H300Chr01
 10  50  H500Chr02

考慮到這一點,我們可以將更改為最後一個(我說的是最後一個而不是第三個,因為這種方法會重新繪製線條並且編號會根據空格的數量而變化)欄位,而無需像這樣更改間距:

$ awk -F'[ ]' '{sub(/.*Chr/,"Chr",$NF);}1' file
start end chr
 1   10  Chr01
 10  50  Chr02

或者,您可以使用perl

$ perl -pne 's/(\s*\S+\s+\S+\s+)\S+(Chr)/$1$2/;' file 
start end chr
 1   10  Chr01
 10  50  Chr02

或者,為了確保您只匹配Chr第三個欄位中的第一次出現,以防有多個:

perl -pe 's/(\s*\S+\s+\S+\s+)\S+?(Chr)/$1$2/;' file 

引用自:https://unix.stackexchange.com/questions/699219