Bash
bash 將行轉換為列
我有數千個看起來像這樣的文件:
org_files:
reference_group1 _CEFNB_ group1 ACBF_BG group2 ACB_MBM ...
對於每個文件,我需要將行轉換為列,然後添加一個包含 reference_group 索引的列(稱為 id_from_reference_group),如下所示:
轉換後的文件
# explanation of each column # reference_group_id serials_from_ref_group group_id serials_from_group reference_group1 _ group1 A reference_group1 group1 C reference_group1 E group1 B reference_group1 F group1 F reference_group1 N group1 _ reference_group1 B group1 B reference_group1 _ group1 G reference_group1 _ group2 A reference_group1 C group2 C reference_group1 E group2 B reference_group1 F group2 _ reference_group1 N group2 M reference_group1 B group2 B reference_group1 _ group2 M
每組的 org_files 中第 2 列的內容由重複的字母組成。並且第二列始終具有相同的長度。
我試過了
input="reference_group1 _CEFNB_ group1 ACBF_BG group2 ACB_MBM" while IFS=" " read -ra line; do # read input line by line # loop over fields for (( i = 0 ; i < ${#line[@]}; i++ )); do # only split 2nd field if [[ $i == 1 ]] then for j in ${line[$i]} do # loopover each letter of 2nd field for (( j=0; j<${#line[$i]}; j++ )) do echo "${line[$i-1]} ${line[$i]:$j:1}" done done fi done done <<< "$input"
但我只得到這樣的結果
reference_group1 _ ... group1 A ... group2 M
而且程式碼有點亂。如果有簡單的命令會更好。謝謝!
您可以使用類似 (
tst.awk
) 的腳本來使用 awk:BEGIN{print "#reference_group_id serials_from_ref_group group_id serials_from_group"} $1 ~ /^reference_/ {ref=$1;ser=$2;next} { for(i=1;i<=length($2);i++){ print ref, substr(ser,i,1), $1, substr($2,i,1) } }
我想你
reference_group_id
總是開始reference_
將它儲存到一個名為 var 的 varref
中,然後儲存serials_from_ref_group
到ser
. 然後我們在一個循環中使用這兩個 var。然後這樣的一行應該可以工作:
awk -f tst.awk file
由於您的輸出是由您格式化的,
column
您可以將輸出通過管道傳輸到column -t
awk -f tst.awk file | column -t
awk 腳本說明:
BEGIN
只執行一次,在第一個輸入記錄之前$1 ~ /^reference_/
if$1
匹配正則表達式^reference_
length($2)
第二個欄位的長度substr(ser,i,1)
子串的ser
起始i
位置和長度1