【发布时间】:2021-10-18 02:56:58
【问题描述】:
当读取一个非常大的制表符分隔文件时:
. . . A . . . . 3:.:.:20
. . . B . . . . 4:.:30
. . . C . . . . 5:.:.:40:.
. . . D . . . . .:.:.:.
. . . A . . . . 7:.:.:21
. . . B . . . . .:.:.:.
. . . D . . . . .:.:.:.
. . . C . . . . .:.:.
我想将第 9 列保留为 .:.:.:.仅当第 4 列 = D。对于所有其他第 4 列值,我有一个单独的 sed 替换查询。所需的输出将如下所示:
. . . A . . . . 1:.:.:80
. . . B . . . . 1:.:80
. . . C . . . . 1:.:.:80:.
. . . D . . . . .:.:.:.
. . . A . . . . 1:.:.:80
. . . B . . . . 1:.:.:80
. . . D . . . . .:.:.:.
. . . C . . . . 1:.:80
我目前的伪代码是这样的:
if [column 4 = D]
then
# either replace or just keep original entry
sed '/some replacement query/g' {file}
else
sed '/some other replacement query/g' {file}
fi
我在想如果我可以逐行读取文件,也许我可以采用这种方法?但后来我不断写信来更新一个新文件。
我不确定如何在 shell 环境中有效地完成这段时间。由于最终目标是创建一个大的最终文件,因此我当前的路线创建了两个不正确的不同版本。也许有一种方法可以在单个 sed 查询中执行我想要的操作?但这超出了我的专业范围。
编辑:sed 替换查询当前查看第 9 列并确定字段分隔符 (":") 的数量并将其替换为相应的值,即 3:.:.:20 变为 1:.:.:80 ,4:.:30 变为 1:.:80 , 和 5:.:.:40:. 变为 1:.:.:80:. 字段分隔符之间的值可以是数字 0-99 或“。”价值。但是,如果第 4 列 = N,则第 9 列必须变为(或在此示例中保持不变).:.:.:. 我当前的替换查询将 .:.:.:. 变为 1:.:.:80,这是我不想要的。
sed 's/\t\(\.\|[0-9]\):\(\.\|\([0-9]\+\)\):\(\.\|\([0-9]\+\)\):\(\.\|\([0-9]\+\)\)$/\t1:\.:\.:80/g;
s/\t\(\.\|[0-9]\):\([0-9],[0-9]\):\(\.\|\([0-9]\+\)\):\(\.\|\([0-9]\+\)\):\(\.\|\([0-9]\+\)\)$/\t1:\.:\.:80:\./g;
s/\t\(\.\|[0-9]\):\(\.\|\([0-9]\+\)\):\(\.\|\([0-9]\+\)\)$/\t1:\.:80/g'
【问题讨论】:
-
.代表标签吗?特别是在最后一个领域?还是这些只是一些任意值? -
.都是其他列值的占位符,除了最后一个字段,一般是列的样子,所以./././.是单列字符串 -
您可以使用
awk还是仅限于sed? -
我可以使用 awk,只要我仍然可以使用非常具体的 sed 查询进行替换...(如果这没有意义,请告诉我)
-
@anita
awk不明白sed的具体查询;它有自己的语言来编辑字符串。 (另一方面,sed不理解列。)您想要进行的实际更改是什么?它可能在awk中表达出来。