我已经尝试了很多年,但还没有接近。使用 awk,如何:将每列中每行 > 1 上的每个 '*' 替换为 '-',但前提是第 1 行中的相应列不是 '*'?
输入示例:
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|*|*|f|g|*|*|*|*|g|c|a|*|A|*
*|s|*|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|*|g|*|T|*|C|g|c|a|a|A|T
输出示例
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T
答案1
需要扫描标题行以查找所有“not *”。
列“没有”*
可以存储在数组中a[]
。
对于所有下一行,仅存在于a[]
可能需要改变。
这可以实现为:
awk -F'|' 'BEGIN{OFS=FS}
NR==1 {
for(i=1;i<=NF;i++) if( $i != "*" ) a[i]
}
NR>1 {
for(i in a) if( $i == "*" ) $i="-"
}
1
' file
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T
这实现了所需的最少更改。应该是最快的。
答案2
一种可能的方法(可能不是最好的)
awk -F'|' '
BEGIN{OFS=FS}
NR==1 {
for(i=1;i<=NF;i++) if($i=="*") a[i]
}
{
for(i=1;i<=NF;i++) if($i=="*" && !(i in a)) $i="-"
}
1
' file
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T