3つの列と任意の数の行(行)を持つファイルがあるとします。各行はxyz座標に対応します。
1 2 3
4 5 6
7 8 9
10 11 12
...
最初と2番目の座標、2番目と3番目の座標、3番目と4番目の座標などの距離をどのように計算しますか?
これが私がすることです。しかし、私の考えはもっと簡単かもしれません。
a=`wc -l < oldfile`
for i in $(seq 2 $a); do
j=$((i-1))
sed -n "${j},${i} p" <oldfile
done > ala
split ala -l 2 ala.
for i in ala.??; do
echo `cat $i`| awk '{printf "%.10f \n", sqrt (($4-$1)^2 + ($5-$2)^2) + ($6-$3)^2}'
done > newfile
どんな答えでも大歓迎です。私はLinuxプログラミングに初めて触れたので、および/またはを使用する簡単なコマンドを使用して非常に感謝しsplit
ます:)。cat
echo
awk
ありがとうございます。
答え1
次のawk
コマンドは、名前付きファイルの1行からスペースで区切られた(x、y、z)座標を読み取り、file
各行間の距離を計算します。
awk '
NR > 1 { printf "%f\n", sqrt(($1-x)^2 + ($2-y)^2 + ($3-z)^2) }
{ x=$1; y=$2; z=$3 }' file
上記のコマンドは、awk
最初の行を除くすべての行について、現在の行に与えられたポイントから前の行に与えられたポイントまでの距離を記録します。変数と には、x
距離値を計算して出力した後に更新された前の行の座標が含まれます。y
z
入力あり
7 4 3
17 6 2
-2 0 0
...結果は
10.246951
20.024984
答え2
使用幸せ(以前のPerl_6)
最初の6つの値(1行あたり3つ)を取得するために問題を単純化します。
raku -e 'my @a = words; for @a -> $x1,$y1,$z1,$x2,$y2,$z2 { \
say sqrt( ($x1 - $x2)**2 + ($y1 - $y2)**2 + ($z1 - $z2)**2) };'
#OR
raku -e 'my @a = words; for @a -> \x1,\y1,\z1,\x2,\y2,\z2 { \
say sqrt( (x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2 ) };'
Rakuは、一部のプログラマが読みやすい符号なし変数(2番目の例)を受け入れます。ファイルは@a
スペースで区切られた配列として読み取られますwords
。 6つの変数が宣言されました(2番目の例):x1,y1,z1
とx2,y2,z2
。距離方程式は、OPが要求したとおりに実行され、値を返します。
[符号なし変数は前にバックスラッシュを使用して宣言されますが、その時点からはバックスラッシュなしで作成できます。符号なし変数は通常不変です(定数宣言に役立ちます。詳細については以下のURLを参照してください)。
入力例(簡略化されたバージョン):
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
16 17 18
出力例(簡易版):
5.196152422706632
5.196152422706632
5.196152422706632
@a
最終バージョンでは、次のようにデータを配列に読み込むときにネストを生成するようRakuに指示するだけですmy @a=lines.rotor(2 => -1).words;
。 @Kusalanandaによって提供されたサンプルデータを使用します。
~$ cat file
7 4 3
17 6 2
-2 0 0
~$ raku -e 'my @a=lines.rotor(2 => -1).words; for @a -> \x1,\y1,\z1,\x2,\y2,\z2 {say sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)};' file
10.246950765959598
20.024984394500787
https://docs.raku.org/言語/variables#index-entry-\_(sigilless_variables)
https://docs.raku.org/routine/rotor
https://raku.org
答え3
「削除」とは、「別々に削除」または「削除」という正確に何を意味しますか?一般的に私は後者を考えますが、PSでは前者を指していると思いますか?
前者を想定すると、シェルで次のことができます。
# index of first row to print
n=3
tail -n +${n} <filename> | head -n 2
与えられたn = 3に対して、これは3行目と4行目を印刷します。
答え4
どういう意味なのかわかりませんが、このソリューションを使用して各行の6D距離を計算します。
awkファイルdist.awk
function memorize()
{ for(i=1;i<=6;i++) previous[i]=$i ;}
NR>1 {
s=0 ;
for(i=1;i<=6;i++) s+=($i-previous[i])**2 ;
printf "dist=%f\n",sqrt(s) ;
}
{
memorize() ;
print ;
}
1
多くの人が好むprint
奇妙なことに、あなたのデータに基づいて次のような結果が得られました。
awk -f dist.awk original.data
1 2 3 4 5 6
dist=14.696938
7 8 9 10 11 12
dist=14.696938
13 14 15 16 17 18
dist=14.696938
19 20 21 22 23 24
(点は6次元空間に整列されており、距離はsqrt(36 * 6)単位です)
要点は、awkが前の行を覚えて計算を実行できることです。