awk + if 문을 사용하여 두 열의 모든 행 조합을 비교합니다.

awk + if 문을 사용하여 두 열의 모든 행 조합을 비교합니다.

11개의 데이터 열이 있는 파일이 있는데 각 열은 공백으로 구분되어 있습니다. 열 2의 각 행에 대해 열 9에서 가장 가까운 값을 찾아야 합니다. 따라서 다음은 열 2(0.01)의 첫 번째 항목을 가져와 열 9(행 3의 0.009)에서 가장 가까운 값을 찾습니다.

파일 레이아웃:

x 0.01 x x x x x x 0.002 x x
x 0.034 x x x x x x 0.0045 x x
x 0.002 x x x x x x 0.009 z z
x 0.002 x x x x x x 0.0021 x x
x 0.015 x x x x x x 0.0031 x x

현재 코드:

awk '{
if (sqrt(($2)^2-($9)^2)<0.0001)
   print "Particle ID  "$1" is within 2D of wall"
}' filename

나는 여기에 두 가지 문제가 있다고 생각합니다.

1) 이것은 모든 순열을 비교하는 것이 아니라 열의 모든 행을 비교합니다.

2) 가장 가까운 범위가 아닌 특정 범위 내에 있는지만 확인합니다.

원하는 출력은 다음과 유사한 새 파일이 됩니다.

x 0.01 x x x x x x 0.009 z z

다른 모든 라인에도 마찬가지입니다.

답변1

awk매크로 사용TXR 불분명한 음성:

$ txr closest.tl < data
x 0.01 x x x x x x 0.009 x x
x 0.034 x x x x x x 0.009 x x
x 0.002 x x x x x x 0.0021 z z
x 0.002 x x x x x x 0.0021 x x
x 0.015 x x x x x x 0.009 x x

코드는 다음 위치에 있습니다 closest.tl.

(build
  (awk
    ((fconv - r : : r - -) (add f))
    (:end (let ((fs (get)))
            (each ((f fs))
              (let ((min (find-min fs : (op abs (- [f 1] [@1 8])))))
                (set [f 8] [min 8])
                (prn . f)))))))

  • build암시적 목록을 프로그래밍 방식으로 구성하기 위한 환경을 만듭니다. 포함된 코드에서는 암시적 목록에 항목을 추가하고 해당 목록을 검색하는 데 build사용합니다 .(add ...)(get)

  • 환경 내부에는 build매크로 인스턴스가 있습니다 awk. 이 매크로에는 조건부 동작 규칙과 :end규칙이 있습니다. 조건-작업 규칙에는 (fconv ...)조건으로 표현식이 있습니다. 이는 무조건 사실이므로 모든 기록을 일치시킵니다. fconv선택한 필드를 부동 소수점(="real")으로 변환합니다 r. 이 작업의 의미는 (add f)현재 필드 목록을 암시적 목록에 추가한다는 것입니다. 따라서 데이터를 필드 목록인 행 목록으로 작성합니다.

    fconvTXR Lisp는 강력한 형식의 언어이기 때문에 이것이 필요합니다. 이 awk매크로는 Awk의 많은 의미를 구현하지만 "3.14"문자열을 숫자로 처리할 수 있는 덕 타이핑을 구현하지 않습니다.

  • :end이 절은 데이터가 끝나면 실행 awk되며 여기서 가장 가까운 처리가 수행됩니다. 행을 라는 변수에 넣고 fs각 행에 대해 하나의 변수를 반복합니다. f각 행에 대해 최소 항을 찾습니다. fs여기서 항은 검사된 각 행에서 해당 행의 필드 1과 필드 8 사이의 차이의 절대값입니다. 최소 거리 행을 찾으면 해당 행의 필드 8을 해당 최소 거리 행의 필드 8로 바꿉니다.

    필드 번호는 0부터 시작됩니다. [f 0], [f 1], ... Awk와 달리 0 필드가 전체 레코드라고 불리는 관례는 없습니다 rec.

  • 필드를 [f 8]최소 거리 필드로 바꾼 후 필드를 인쇄합니다.

관련 정보