我有许多大的TSV文件,其中有6个未命名的列和大约Linux0万行.我需要逐行应用更改并另存为新的TSV.我在Linux上工作,并有权访问awk,gawk,grep.理想情况下,代码将在其运算符中引用列号,因此它的功能与行内容无关.蒂娅!

只需对第2列和第3列进行更改,但更改取决于第6列中的值:

If the value of column 6 is "+", then:  
New Column 2: [Column 2 Value]  
New Column 3: [Column 2 Value] + 1  
  
If the value of column 6 is "-", then:  
New Column 2: [Column 3 Value] - 1  
New Column 3: [Column 3 Value]  

Example TSV Data Structure (no | present in actual data)

| AI     | 828     | 878     | ABC4807:78485:5:79215       | 42 | - |
| AI     | 971     | 1021    | ABC248:78485:5:79215:46065  | 42 | + |
| AI     | 1104    | 1153    | X7481:78485:5:79215:40174   | 35 | - |
| XVDIII | 56939   | 56988   | 9478:78485:5:79215:30872    | 42 | - |
| XVDIII | 56971   | 57020   | 7841S:78485:5:79215:34301   | 42 | - |
| UTXV   | 1043196 | 1043246 | T885189:78485:5:79215:10036 | 42 | + |
| UTXV   | 1043198 | 1043248 | C74581:78485:5:79215:10792  | 42 | - |
| UTXV   | 1043201 | 1043250 | T75S17:78485:5:79215:30204  | 42 | - |
| UTXV   | 1043201 | 1043251 | B784W7:78485:5:79215:42548  | 42 | - |

Desired TSV Output

| AI     | 877     | 878     | ABC4807:78485:5:79215       | 42 | - |
| AI     | 971     | 972     | ABC248:78485:5:79215:46065  | 42 | + |
| AI     | 1152    | 1153    | X7481:78485:5:79215:40174   | 35 | - |
| XVDIII | 56987   | 56988   | 9478:78485:5:79215:30872    | 42 | - |
| XVDIII | 57019   | 57020   | 7841S:78485:5:79215:34301   | 42 | - |
| UTXV   | 1043196 | 1043197 | T885189:78485:5:79215:10036 | 42 | + |
| UTXV   | 1043247 | 1043248 | C74581:78485:5:79215:10792  | 42 | - |
| UTXV   | 1043249 | 1043250 | T75S17:78485:5:79215:30204  | 42 | - |
| UTXV   | 1043250 | 1043251 | B784W7:78485:5:79215:42548  | 42 | - |

推荐答案

替换这些值的算法不是问题. 有趣的一点是维护固定宽度的列.

文件:dataconvert.awk文件:dataconvert.awk

#!/usr/bin/gawk -f

BEGIN {
    OFS = FS = "|"
}
{
    if ($7 ~ /+/) {
        len = length($4)
        $4 = $3
        gsub(/\s+/, "", $4)
        $4 = substr((" " ($4 + 1) "                       "), 0, len)
    } else {
        if ($7 ~ /-/) {
            len = length($3)
            $3 = $4
            gsub(/\s+/, "", $3)
            $3 = substr((" " ($3 - 1) "                       "), 0, len)
        }
    } 
    print
}

chmod +x dataconvert.awk标记为可执行文件,然后直接拨打./dataconvert.awk即可启动

在这个解决方案中,列内容的宽度被存储,结果用节省的空间填充,最后被裁剪到存储的长度.

如果数据集在第6列提供值+-确实没有异常,则可以省略第二个if子句.在大型数据集上,这可以节省一些时间.

由于数据集以字段分隔符开头,因此第一列始终为空,但存在.因此,按照直观的计数方式,列计数必须为+1.

Linux相关问答推荐

抛出主,即未捕获到SIGSEGV中的异常结果

C++17/Linux:信号未解锁单独线程中被阻止的网络套接字调用

如何检测文件系统是否支持权限?

删除第二列中数字为零的行

eBPF:仅使用系统调用加载 eBPF 程序并将其附加到 sys_enter_execve

Linux 上 Ada 任务优先级的语义是什么?

在 bash 中使用 tee 时如何返回错误代码

X86 程序集 - struct 点 - 存储/返回不正确?

使用ansible配置Linux VM使用vmware_vm_shell模块时变成su?

提交SLURM作业(job)时出现nohup问题

使用 awk 将索引列添加到 csv

如何计算制表符分隔的文本文件中字段的唯一值的数量?

使用 AWS cli 从 AWS 机密管理器解析机密

如何测试是否存在两个文件?

在 cron 作业(job)中执行 PHP 脚本

在 bash 中检测公共 IP 地址的方法

使用 Scp 时防止覆盖文件

你如何在 C 中的 Linux 上进行非阻塞控制台 I/O?

带有 curl 的 Linux 脚本来判断 Web 服务是否已启动

何时使用管道与何时使用共享内存