Вычисление евклидовых расстояний с помощью awk не дает ожидаемого результата

в качестве входных данных для расчета расстояния у меня есть файл (inp.txt), содержащий координаты:

9.911 -2.781 30.097 7.768 -4.335 29.094
11.811 -1.900 30.082 13.294 -1.993 27.440
6.947 -0.742 31.786 6.390 -2.976 30.089
8.960 -2.090 32.359 11.764 1.604 25.408
9.156 -3.314 29.815 11.764 1.604 25.408

Первые три столбца — это координаты точки (скажем, A), а последние три — координаты второй точки (скажем, B). Я хочу рассчитать расстояние между A и B и всеми остальными точками, расположенными таким же образом в следующих строках. Затем я ожидаю, что в этом случае на выходе будет 5 значений расстояния.

Мой код awk, который я использую для этой цели:

awk '{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' inp.txt >> out.txt

При входе получаю ошибку:

 awk: fatal: cannot open file `{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' for reading (No such file or directory)

Я безуспешно пытался понять, почему я получаю эту ошибку. Спасибо за любую помощь.


person Maurizio Cirilli    schedule 16.08.2020    source источник


Ответы (2)


Находится ли входной файл там, где вы думаете? Ваш скрипт у меня работает с inp.txt в текущем каталоге. Если я намеренно ссылаюсь на неправильное имя файла, возникает ошибка, аналогичная вашей:

t2$ awk '{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} {print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' inpBAD.txt
awk: fatal: cannot open file `inpBAD.txt' for reading (No such file or directory)

Кроме того, вам, вероятно, не нужно условие END, если вы ожидаете значение для каждой строки, а не только для последней...

t2$ awk '{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' inp.txt
7.1

t2$ awk '{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} {print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' inp.txt
2.83079
3.03119
2.86021
8.3561
7.1
person Ian McGowan    schedule 16.08.2020
comment
Спасибо Ян. Да, это было плохое имя файла. Извините за глупый вопрос. В любом случае, вы помогли мне с итерацией. Не могли бы вы объяснить, почему END мешает итерации в awk? Я думал, что это обязательно для моих целей. - person Maurizio Cirilli; 17.08.2020
comment
Нет, неправильное или отсутствующее имя файла не приводило к появлению сообщения об ошибке awk: fatal: cannot open file `{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' for reading (No such file or directory). - person Ed Morton; 17.08.2020
comment
Спасибо, Эд, ваш ответ на самом деле правильный здесь, вы получаете мой голос. Маурицио, условие END выполняется только после прочтения всех строк — в этот момент запускается действие после окончания. Если вы хотите обрабатывать каждую строку ввода, то в этом скрипте нет необходимости в END. Обычно он используется, когда вы хотите обобщить некоторые данные, а затем показать сводную информацию. - person Ian McGowan; 20.08.2020

Вы сделали awk -f '{x1=$1;...}' или awk 'foo' '{x1=$1;...}' вместо awk '{x1=$1;...}', поэтому awk пытался открыть скрипт, как если бы это было имя файла. Последнее более вероятно, учитывая это конкретное сообщение об ошибке. Смотреть:

$ awk -f '{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' inp.txt >> out.txt
awk: fatal: cannot open source file `{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' for reading: No such file or directory

$ awk '7' '{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' inp.txt >> out.txt
awk: fatal: cannot open file `{x1=$1;y1=$2;z1=$3} {x2=$4;y2=$5;z2=$6} END{print sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)}' for reading: No such file or directory
person Ed Morton    schedule 17.08.2020