#!/usr/bin/env bash # # a.txt(라우팅 경로 목록)와 b.txt(URI 목록)를 읽어, 각 URI가 어느 라우팅 경로에 # 매핑되는지 계산해 CSV로 출력한다. # # 사용법: ./map_routes.sh [routes_file] [uris_file] [output_csv] # 기본값: a.txt, b.txt, mapping.csv # # 매핑 규칙: # - 라우팅 경로는 URI의 접두사(prefix)로 매칭된다. (예: "/building2/abcd" -> "/building") # - 라우팅 경로 안의 "\\d" (이중 백슬래시 + d) 는 숫자 한 글자를 의미하므로 "[0-9]" 로 변환해 # 매칭한다. (예: "/search/v\\d.\\d") # - 한 URI가 여러 라우팅 경로에 동시에 매칭될 수 있는 경우, 실제로 매칭된 문자열이 # 가장 긴(가장 구체적인) 라우팅 경로를 선택한다. # - 매칭되는 라우팅 경로가 없으면 "NOT_MATCHED" 로 표시한다. # # route 개수 x uri 개수가 커도(예: 60 x 2000+) 빠르게 끝나도록, URI/route 조합마다 # 별도 프로세스(sed/grep 등)를 fork 하지 않고 awk 프로세스 1개 안에서 전부 처리한다. set -euo pipefail ROUTES_FILE="${1:-a.txt}" URIS_FILE="${2:-b.txt}" OUTPUT_FILE="${3:-mapping.csv}" if [[ ! -f "$ROUTES_FILE" ]]; then echo "라우팅 경로 파일을 찾을 수 없습니다: $ROUTES_FILE" >&2 exit 1 fi if [[ ! -f "$URIS_FILE" ]]; then echo "URI 파일을 찾을 수 없습니다: $URIS_FILE" >&2 exit 1 fi { echo "uri,routing_path" awk ' # 첫 번째 입력 파일(routes_file): 라우팅 경로 목록을 배열로 적재 FNR == NR { if (FNR == 1) next # 헤더 스킵 if ($0 == "") next # 빈 줄 스킵 route = $0 pattern = route gsub(/\\\\d/, "[0-9]", pattern) # "\\d" -> "[0-9]" nroutes++ routes[nroutes] = route patterns[nroutes] = "^" pattern next } # 두 번째 입력 파일(uris_file): 각 URI에 대해 가장 구체적인(가장 길게 매칭되는) route 탐색 { if (FNR == 1) next # 헤더 스킵 if ($0 == "") next # 빈 줄 스킵 uri = $0 best_len = -1 best_route = "" for (i = 1; i <= nroutes; i++) { if (match(uri, patterns[i]) == 1 && RLENGTH > best_len) { best_len = RLENGTH best_route = routes[i] } } if (best_route == "") best_route = "NOT_MATCHED" u = uri; gsub(/"/, "\"\"", u) r = best_route; gsub(/"/, "\"\"", r) print "\"" u "\",\"" r "\"" } ' "$ROUTES_FILE" "$URIS_FILE" } > "$OUTPUT_FILE" echo "생성 완료: $OUTPUT_FILE"