
我有一個這樣的文件
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/\..*//'