从文本文件中的不同位置删除值

从文本文件中的不同位置删除值

我有一个以 3x66 矩阵排列的文本文件mat.txt,如下所示:

0 -1 0.000532 -0.00026 0.000465 etc...
0 0.000294 1 -0.000102 -0.1146 etc...
0 -0.000134 0.0000967 1 -0.9972 etc...

这些值可以被视为 3D 坐标对,其中每行的第一个值表示 (x,y,z) 坐标,每行的第二个值表示另一个 (x,y,z) 坐标,依此类推。除了开头的零之外,数字随文件而变化,因此我需要根据文本文件中的位置而不是字符串来定位。

我需要从文件中删除某些坐标,坐标取决于它是哪个文件。我想也许可以用来awk分隔和删除整个列,但我不确定如何动态读取要删除的列。我有单独的文本文件,其中包含需要删除的列。

例如:

cat delete.txt
2 5 18 27 59

我可以使用 awk 来隔离和删除第 2、5、18 等列吗?

for i in $(cat delete.txt)
do
awk '{print $i}' | rm $i << mat.txt
done

答案1

如果infile是:

0 -1 0.000532 -0.00026 0.000465 etc...
0 0.000294 1 -0.000102 -0.1146 etc...
0 -0.000134 0.0000967 1 -0.9972 etc...

delete是您要从您的喜欢中删除它们的列号infile

2 4 6

awk,你可以这样做:

awk 'NR==FNR { split($0, to_delete); next }
             # split 'delete' file into an array called to_delete on default FS (white-space)
             { for (col in to_delete) $to_delete[col]=""; print }' delete infile
             # delete the columns from 'infile' that match with $column getting from array

这将为您提供从文件中删除第 2、4 和 6 列的输出。

0  0.000532  0.000465
0  1  -0.1146
0  0.0000967  -0.9972

答案2

听起来这就是您正在寻找的:

awk '
NR==FNR { split($0,del); next }
{
    out = sep = ""
    for (i=1; i<=NF; i++) {
        if ( !(i in del) ) {
            out = out sep $i
            sep = OFS
        }
    }
    print out
}
' delete.txt mat.txt

答案3

假设delete.txt只有一行,我们可以使用以下代码获取所需的列:

$ perl -psale '$. == 1 and 
   @indices2P = grep { my $c=$_+1; $d !~ /\b$c\b/ } 0 .. $#F;
   $_ = "@F[@indices2P]";
' -- -d="$(< delete.txt)" mat.txt

结果:

0 0.000532 0.000465
0 1 -0.1146
0 0.0000967 -0.9972

解释:

将要删除的列存储在标量变量中$d,并在读取文件的第一行mat.txt计算需要打印的列索引。

然后在访问数组@F进行打印时仅应用这些索引。

答案4

$ < delete.txt \
       tr -s ' \t' '\n\n' | sort -nru |
       sed -e 's|.*|s/\\s*\\S+//&|' |
       sed -Ef - mat.txt

结果:

0 0.000532 0.000465
0 1 -0.1146
0 0.0000967 -0.9972

解释:

使用打开扩展正则表达式模式的 GNU sed,我们首先生成一个 sed 代码,当应用于 mat.txt 文件时,我们会得到我们喜欢的输出。

假设:

o The file delete.txt comprises only positive integers and max value < 512

相关内容