刪除列中的副檔名

刪除列中的副檔名

我有一個這樣的文件

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402.5
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046.3
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838.1

我想刪除第三列末尾的數字擴展名,以便我的輸出檔案如下所示

ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

我怎樣才能最好使用命令列來完成它awk?我可以做到這一點,perl但我很確定有一個命令列可以做到這一點。

答案1

使用 awk:

awk -F'.' '{print $1}' file

-F選項將預設欄位分隔符號(空格)變更為點(.)。
$1是欄位位置的索引(帶有 . 欄位分隔符號)。

{ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402}.{5}
                  ^^ field index is $1                                          ^^$2

使用 rev 和 awk:

rev file | awk -F'.' '{print $2}'|rev # reverse characters of each lines,\
                                        print field number 2 with (.) separator \
                                        and reverse the result again

rev實用程式將指定的檔案複製到標準輸出,反轉每行中的字元順序。如果未指定文件,則讀取標準輸入。

使用 sed:

sed 's/.[0-9]*$//' file

sed 's/.[^.]*$//' file

$指向行尾。在第一個 sed 指令中搜尋 char(.),後面跟著零個或多個出現的數字,並將它們替換為空格。

在第二個 sed 指令中,刪除 (.) 後面的所有內容,並刪除點 (.) 本身。

使用 rev 和 sed:

rev file| sed 's/.*[.]//' |rev

刪除點(.)之前的所有內容,同時包含和刪除 .本身。

使用 grep:

grep -oP '.*(?=\.[0-9])' file
    -o, --僅匹配
          僅列印匹配行的匹配(非空)部分,
          每個這樣的部分都在單獨的輸出線上。
    -P, --perl-正規表達式
          將 PATTERN 解釋為 Perl 相容的正規表示式 (PCRE)

(?=pattern):正向先行:正向先行結構是一對括號,左括號後面跟著一個問號和一個等號。

.*(?=\.[0-9]):(正向先行)匹配所有內容 ( .*) 後面跟著一個點 (.) 和任何出現的數字,而不使模式 ( \.[0-9]) 成為匹配的一部分。

使用 rev 和 grep:

rev file |grep -oP '(?<=[0-9]\.).*' |rev

rev file |grep -oP '[0-9]\.\K.*' |rev

(?<=pattern):積極的後視。一對括號,左括號後面跟著一個問號、「小於」符號和一個等號。

(?<=[0-9]\.).*(正向後查找)符合後面出現的任何數字並以點 (.) 結尾的所有內容。

在第二個 grep 指令中,您可以使用 nifty來\K取代lookbehind 斷言。

附切割:

cut -f1 -d. file

cut -c 1-77 file # Print first 77 characters of each line.
cut - 從檔案的每一行中刪除部分

-d, --delimiter=DELIM
      使用 DELIM 而不是 TAB 作為欄位分隔符

-f, --fields=列表
      僅選擇這些欄位;

-c, --字元=列表
      僅選擇這些字符

使用 while 迴圈:

while read line; do echo "${line::-2}";done <file

如果每行末尾只有長度=1 的數字且它們是固定長度,則這將起作用。上面的命令刪除輸入檔案中每行末尾的最後兩個字元。替代命令是${line%??}.

答案2

假設擴展名是全數字:

perl -pi -e 's/\.\d+$//' /path/to/file

-i進行就地編輯(如sed)。\d表示數字,$表示行尾。

awk

awk 'gsub(/\.[0-9]+$/,"")' /path/to/file

gawk在較新的版本中有一個就地編輯選項,但我不確定它的便攜性如何。gsub支援可選參數,指定目標列:

awk 'gsub(/\.[0-9]+$/,"",$3)' /path/to/file

最後一種形式具有不良的副作用,即在其輸出中以單個空格分隔每列,就像您所做的那樣print $1,..,$NF。我不知道為什麼。

答案3

使用awk它很簡單,只需將字段分隔符號設為.

awk -F. '{print $1}' file

另一種方法是使用 shell(在本例中為 bash):

while IFS=.; read -r lines _; do  line+=("$lines"); done <file                                                                           
printf "%s\n" "${line[@]}"
ILMN_1343291    TGTGTTGAGAGCTTCTCAGACTATCCACCTTTGGGTCGCTTTGCTGTTCG  NM_001402
ILMN_1343295    CTTCAACAGCGACACCCACTCCTCCACCTTTGACGCTGGGGCTGGCATTG  NM_002046
ILMN_1651209    TCACGGCGTACGCCCTCATGGGGAAAATCTCCCCGGTGACTTTCAGGTCC  NM_182838

答案4

這會刪除以點開頭的所有內容:

sed 's/\..*//'

相關內容