Hil*_*ill 4 unix awk replace sed
我有一个制表符分隔的文件,其中至少有16列(但可能更多),其中第一列是唯一标识符; 和> 10,000行(示例中仅显示6x6),如下所示:
ID VAR1 VAR2 VAR3 VAR4 VAR5
1 1 1 1 1 1
2 -9 -9 -9 -9 -9
3 3 3 3 3 3
4 4 4 4 -9 4
5 5 5 5 5 5
6 6 -9 6 6 6
Run Code Online (Sandbox Code Playgroud)
如果其中一个值已经是"-9",我需要将VAR1-5的所有值更改为"-9"
所以,期望的输出将是:
ID VAR1 VAR2 VAR3 VAR4 VAR5
1 1 1 1 1 1
2 -9 -9 -9 -9 -9
3 3 3 3 3 3
4 -9 -9 -9 -9 -9
5 5 5 5 5 5
6 -9 -9 -9 -9 -9
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经尝试过像这样的awk:
awk -F'\t' '
BEGIN{OFS="\t"}
{for(i=2;i<=NF;i++){if ($i=="-9"){for(j=2;j<=NF;j++){$j="-9"};continue}}};1
' < file1.tab
Run Code Online (Sandbox Code Playgroud)
哪个适用,但在应用于实际数据集时非常慢.有更快的方法吗?也许是grep和sed?结合的东西?
这是一个不会对列数进行硬编码的变体.
awk -F '\t' '/(^|\t)-9(\t|$)/ {
printf $1; for(i=2; i<=NF; ++i) printf "\t-9"; printf "\n"
next }
1' file1 file2
Run Code Online (Sandbox Code Playgroud)
这里的主要优化是Awk立即扫描整行并立即触发正则表达式,而不需要遍历所有字段,除非它已经知道存在匹配.
因为我们知道除了第一个字段之外我们将丢弃所有字段,所以不需要让Awk替换字段以便它们可以打印它们.只需生成我们想要打印的输出并继续前进,而无需触及Awk的内部线条表示.这也应该购买几个周期,尽管这是一个非常小的性能改进.