소개
텍스트 파일은 여러 방식으로 서로 관련될 수 있습니다. 문자를 정규화해야 할 때도 있고, 두 파일이 줄 위치에 따라 대응할 때도 있으며, 레코드가 키를 공유할 때도 있습니다. 옵션을 외우는 것보다 상황에 맞는 도구를 선택하는 일이 더 중요합니다.
이 실습에서는 세 가지 도구를 중점적으로 다룹니다. tr은 문자 스트림을 변환하고, paste는 위치에 따라 줄을 결합하며, join은 공통 필드를 기준으로 정렬된 레코드를 결합합니다. 각 입력을 확인하고 결과 파일을 검증한 다음, 간단한 보고서를 작성합니다.
문자 스트림 변환 및 정리
이 단계에서는 tr을 사용해 문자를 변환하고, 반복되는 구분자를 하나로 줄이며, 필요 없는 문자를 삭제합니다.
일부러 일관되지 않은 줄을 만듭니다. cat -A를 사용하면 일반적으로 보이지 않는 세부 정보가 표시됩니다. 공백은 빈 간격으로 남고 $는 줄 끝을 나타냅니다. 이를 통해 정리해야 할 내용을 정확히 확인할 수 있습니다.
cd /home/labex/project/text-combine-lab
printf ' API,,,Worker,,WEB \n' > raw-services.txt
cat -A raw-services.txt
tr SET1 SET2는 첫 번째 집합의 문자를 두 번째 집합의 해당 문자로 바꿉니다. 이식 가능한 클래스 [:upper:]와 [:lower:]는 각각 대문자와 소문자를 나타냅니다.
tr '[:upper:]' '[:lower:]' < raw-services.txt
이제 세 단계를 파이프로 연결합니다. 첫 번째 tr은 영문자의 대소문자를 변환합니다. tr -s ','는 반복되는 쉼표가 이어진 각 구간을 쉼표 하나로 압축 (squeeze) 합니다. tr -d ' '는 공백 문자를 삭제 (delete) 합니다. tee는 최종 스트림을 화면에 표시하면서 파일에도 저장합니다.
tr '[:upper:]' '[:lower:]' < raw-services.txt | tr -s ',' | tr -d ' ' | tee clean-services.txt
결과는 api,worker,web이어야 합니다. tr은 스트림을 읽으며 입력 파일을 제자리에서 수정하지 않습니다.
paste 로 대응하는 줄 병합
이 단계에서는 첫 번째 줄끼리, 두 번째 줄끼리 대응하는 파일을 결합합니다.
서비스 이름으로 구성된 열 하나와 담당 팀으로 구성된 열 하나를 만듭니다.
cd /home/labex/project/text-combine-lab
printf '%s\n' api worker web > services.txt
printf '%s\n' team-blue team-green team-blue > owners.txt
paste는 기본적으로 탭을 사용해 대응하는 줄을 나란히 배치합니다.
paste services.txt owners.txt
-d,를 사용해 구분자를 쉼표로 지정하고, tee로 CSV 와 비슷한 파일을 화면에 표시하면서 저장합니다.
paste -d, services.txt owners.txt | tee service-owners.csv
paste는 키를 비교하지 않습니다. 한 파일에서 줄이 누락되거나 순서가 바뀌면 줄의 대응 관계도 달라집니다.
공통 키를 기준으로 레코드 조인
이 단계에서는 줄 위치가 아니라 일치하는 첫 번째 필드를 기준으로 레코드를 결합합니다.
순서가 서로 다른 공백 구분 테이블 두 개를 만듭니다.
cd /home/labex/project/text-combine-lab
printf '%s\n' 'web 8080' 'api 9000' 'worker 9100' > ports-unsorted.txt
printf '%s\n' 'worker active' 'web active' 'api maintenance' > states-unsorted.txt
join은 두 입력이 조인 필드를 기준으로 정렬되어 있다고 가정합니다. 정렬된 복사본을 준비합니다. sort -k1,1에서 -k는 키를 선택하고, 1,1은“필드 1 에서 시작해 필드 1 에서 끝낸다”는 뜻입니다. 따라서 서비스 이름만 정렬 순서를 결정합니다.
sort -k1,1 ports-unsorted.txt > ports.txt
sort -k1,1 states-unsorted.txt > states.txt
두 파일의 내용을 확인한 다음, 필드 1 의 값이 일치하는 레코드를 조인합니다.
cat ports.txt
cat states.txt
join ports.txt states.txt | tee service-details.txt
각 결과에는 공통 서비스 키가 한 번 표시된 후 포트와 상태가 이어집니다.
읽기 쉬운 서비스 보고서 작성
이 단계에서는 원본 테이블을 변경하지 않고 조인된 레코드의 형식을 바꿉니다.
공백을 쉼표로 변환해 간단한 보고서를 만듭니다.
cd /home/labex/project/text-combine-lab
tr ' ' ',' < service-details.txt | tee service-report.csv
두 명령을 그룹으로 묶어 헤더를 추가합니다. 중괄호를 사용하면 두 명령의 출력이 하나의 리디렉션으로 전달됩니다.
{ echo 'service,port,state'; cat service-report.csv; } > service-report-with-header.csv
cat service-report-with-header.csv
헤더를 제외하고 데이터 레코드 수를 셉니다.
tail -n +2 service-report-with-header.csv | wc -l | tr -d ' ' > service-count.txt
cat service-count.txt
이 작업 흐름은 정규화된 데이터, 조인된 데이터, 형식이 지정된 데이터, 최종 보고서라는 작고 확인하기 쉬운 단계를 유지합니다.
요약
문자 수준의 정규화에는 tr을, 위치에 따른 열 결합에는 paste를, 정렬된 키 관계의 결합에는 join을 사용했습니다. 그런 다음 원본 입력을 그대로 유지하면서 작은 단계들을 결합해 읽기 쉬운 CSV 보고서를 작성했습니다.



