次のように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)座標を表し、各行の2番目の値は異なる(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
[OK]から削除したい列番号は次のとおりです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に行が1つしかないと仮定すると、次のコードを使用して必要な列を取得できます。
$ 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を使用して、最初にmat.txtファイルに適用したときに目的の出力を提供するsedコードを生成します。
仮定:
o The file delete.txt comprises only positive integers and max value < 512