我有数千个如下所示的文件:
组织文件:
reference_group1 _CEFNB_
group1 ACBF_BG
group2 ACB_MBM
...
对于每个文件,我需要将行转换为列,然后添加一列(称为 id_from_reference_group),该列由 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中第二列的内容由重复的字母组成。并且第二列始终具有相同的长度。
我试过
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
而且代码有点乱。如果有简单的命令就更好了。谢谢!
答案1
您可以使用 awk 使用类似 ( ) 的脚本tst.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 中ref
,然后将其存储serials_from_ref_group
到ser
.然后我们在循环中使用这两个变量。
那么这样的一行应该可以工作:
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