You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Bash脚本查找与指定人员距离最近的人员姓名及对应距离

Bash Script to Find Closest 3D Distance from a Specified Person

Problem Context

I need to write a Bash script proj01.sh that calculates the closest 3D distance from a specified person (via index) to others in a CSV file, then outputs the closest person's name and distance. Here's the full breakdown of requirements and where I'm stuck:


Files & Input/Output Details

Sample Input File (sampleInputFile)

Name, Xloc, YLoc, Zloc
John, 10.5, 80.1, 5.80
Mary, 30.4, 20.5, 9.20
Paul, 10, 1000.0, 10.6

Expected Usage & Output

Input command: proj01.sh sampleInputFile 1
Output (to correspondingOutputFile and console): Mary 62.9 (or rounded to 63.0)

Core Requirements

  1. Validate that the input file exists; exit with an error message if not.
  2. Validate the person index is a positive integer within the range of available entries.
  3. Calculate 3D distance using the formula:
    d = sqrt( (x1-x2)² + (y1-y2)² + (z1-z2)² )

My Current Progress

I can read the file's rows, but I'm unsure how to extract the target person's coordinates, compare them to all others, and find the minimum distance. Here's my code snippet so far:

{
  read
  while IFS=, read -r n x y z
  do
    echo "n: $n x: $x y: $y z: $z"
  done
} < $inputFile

Complete Solution Script

Here's a full implementation of proj01.sh that covers all your requirements, with explanations for key parts:

#!/bin/bash

# Check if we have exactly 2 arguments
if [ $# -ne 2 ]; then
    echo "Usage: $0 <input-file> <person-index>"
    exit 1
fi

input_file="$1"
target_idx="$2"

# Validate input file exists
if [ ! -f "$input_file" ]; then
    echo "Error: File '$input_file' does not exist."
    exit 1
fi

# Validate index is a positive integer
if ! [[ "$target_idx" =~ ^[0-9]+$ ]]; then
    echo "Error: Person index must be a positive integer."
    exit 1
fi

# Count total number of people (skip header row)
total_people=$(tail -n +2 "$input_file" | wc -l)

# Validate index is within valid range
if [ "$target_idx" -lt 1 ] || [ "$target_idx" -gt "$total_people" ]; then
    echo "Error: Person index must be between 1 and $total_people."
    exit 1
fi

# Extract target person's name and coordinates
# Skip header, grab the target row, clean up commas/whitespace
read -r target_name target_x target_y target_z <<< "$(tail -n +2 "$input_file" | sed -n "${target_idx}p" | tr ',' ' ' | xargs)"

# Initialize variables for tracking minimum distance
min_dist_sq=999999999  # Using squared distance to avoid sqrt until final step
closest_name=""

# Loop through all people to calculate distances
{
    read  # Skip header row
    current_line=1
    while IFS=, read -r name x y z; do
        # Skip the target person themselves
        if [ "$current_line" -eq "$target_idx" ]; then
            current_line=$((current_line + 1))
            continue
        fi

        # Clean up whitespace from coordinates
        x=$(echo "$x" | xargs)
        y=$(echo "$y" | xargs)
        z=$(echo "$z" | xargs)

        # Calculate squared differences (using bc for floating point math)
        dx=$(echo "$target_x - $x" | bc)
        dx_sq=$(echo "$dx * $dx" | bc)
        dy=$(echo "$target_y - $y" | bc)
        dy_sq=$(echo "$dy * $dy" | bc)
        dz=$(echo "$target_z - $z" | bc)
        dz_sq=$(echo "$dz * $dz" | bc)

        # Sum squared differences (squared distance)
        dist_sq=$(echo "$dx_sq + $dy_sq + $dz_sq" | bc)

        # Update minimum distance if current is smaller
        if (( $(echo "$dist_sq < $min_dist_sq" | bc -l) )); then
            min_dist_sq="$dist_sq"
            closest_name="$name"
        fi

        current_line=$((current_line + 1))
    done
} < "$input_file"

# Calculate final distance (sqrt of squared distance) with 1 decimal place
final_dist=$(echo "scale=1; sqrt($min_dist_sq)" | bc)

# Output to both console and correspondingOutputFile
echo "$closest_name $final_dist" | tee correspondingOutputFile

Key Explanations

  1. Input Validation:
    • We first check argument count, file existence, index format, and index range to avoid runtime errors.
  2. Target Data Extraction:
    • tail -n +2 skips the header, sed -n "${target_idx}p" grabs the specific row, and tr/xargs cleans up commas and extra whitespace to make variable assignment easy.
  3. Distance Calculation:
    • We use squared distance instead of actual distance for comparisons (since sqrt is a monotonic function, the smallest squared distance corresponds to the smallest actual distance) – this saves computation time.
    • bc is used for floating-point arithmetic, which Bash doesn't handle natively.
  4. Result Output:
    • tee writes the result to both the console and correspondingOutputFile as required.

Test It Out

Run the script with your sample input:

chmod +x proj01.sh
./proj01.sh sampleInputFile 1

You'll get the output Mary 62.9 (and the same line in correspondingOutputFile).

内容的提问来源于stack exchange,提问作者Malapati Chetan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:17:43