CSV to Markdown
CSV를 Markdown 테이블로 변환
CSV 입력
Markdown 출력
CSV to Markdown 변환이란?
CSV를 Markdown 테이블로 변환하는 것은 개발자들이 자주 수행하는 작업입니다. CSV(Comma-Separated Values)는 각 행이 별도의 줄에 위치하고 필드가 쉼표나 탭 같은 구분자로 구분되는 일반 텍스트 형태로 표 형식 데이터를 저장합니다. CSV는 스프레드시트, SQL 클라이언트, 분석 도구의 기본 내보내기 형식입니다. CSV 파일은 간결하고 생성하기 쉽지만, 데이터가 표시될 때 어떻게 보일지 제어하는 기본 방법이 없습니다. 텍스트 편집기에서 열면 쉼표로 구분된 문자열의 나열로, 기계는 읽을 수 있지만 사람이 훑어보기에는 불편합니다.
Markdown 테이블은 이 가독성 문제를 해결합니다. GitHub Flavored Markdown(GFM) 명세에 따라 정의되며 GitHub, GitLab, Bitbucket, Notion, Obsidian, 그리고 Hugo와 Jekyll 같은 정적 사이트 생성기에서 지원됩니다. Markdown이 처리되는 어디서든 깔끔한 HTML 테이블로 렌더링됩니다. 문법은 열을 구분하는 파이프 문자와 헤더 행과 본문 행 사이의 필수 구분자 행(대시로 구성)을 사용합니다.
CSV를 Markdown 테이블로 변환한다는 것은 각 행을 파이프로 구분된 문법으로 감싸고 헤더 뒤에 구분자 행을 삽입하는 것을 의미합니다. CSV의 첫 번째 행이 테이블 헤더가 되고, 이후 각 행이 본문 행이 됩니다. README, 풀 리퀘스트 설명, 위키 페이지, 또는 Markdown 문서 시스템에 구조화된 데이터를 붙여넣어야 할 때마다 이 변환이 필요합니다.
이 도구를 사용하는 이유
이 변환기는 브라우저에서 CSV를 파싱하고 Markdown 테이블 출력을 즉시 생성하며, 데이터를 서버로 전송하지 않습니다.
CSV to Markdown 활용 사례
Markdown 테이블 문법 참조
Markdown 테이블은 GitHub Flavored Markdown(GFM) 명세를 따릅니다. 모든 테이블은 헤더 행, 구분자 행, 그리고 하나 이상의 본문 행이 필요합니다. 구분자 행이 컬럼 정렬을 제어합니다.
| 요소 | 문법 | 설명 |
|---|---|---|
| Column separator | | | Separates each cell within a row |
| Header row | | Name | Age | | First row of the table, defines column names |
| Separator row | | --- | --- | | Required second row; separates header from body |
| Left align | | :--- | | Default alignment — colon on the left side |
| Center align | | :---: | | Colons on both sides of the dashes |
| Right align | | ---: | | Colon on the right side only |
| Escaped pipe | \| | Use backslash to include a literal pipe in cell text |
CSV vs Markdown 테이블
두 형식 모두 일반 텍스트로 표 형식 데이터를 표현합니다. CSV는 기계와 데이터 파이프라인용이고, Markdown 테이블은 문서를 읽는 사람용입니다.
코드 예제
다음 예제는 다양한 언어에서 CSV를 Markdown 테이블로 프로그래밍 방식으로 변환하는 방법을 보여줍니다. 각 예제는 유효한 GFM 테이블을 생성합니다.
const csv = `name,age,city
Alice,30,Berlin
Bob,25,Tokyo`
const [headerLine, ...rows] = csv.trim().split('\n')
const headers = headerLine.split(',')
const separator = '| ' + headers.map(() => '---').join(' | ') + ' |'
const headerRow = '| ' + headers.join(' | ') + ' |'
const bodyRows = rows.map(row =>
'| ' + row.split(',').join(' | ') + ' |'
)
const markdown = [headerRow, separator, ...bodyRows].join('\n')
// → | name | age | city |
// → | --- | --- | --- |
// → | Alice | 30 | Berlin |
// → | Bob | 25 | Tokyo |import csv
import io
csv_string = """name,age,city
Alice,30,Berlin
Bob,25,Tokyo"""
reader = csv.reader(io.StringIO(csv_string))
rows = list(reader)
headers = rows[0]
lines = []
lines.append('| ' + ' | '.join(headers) + ' |')
lines.append('| ' + ' | '.join('---' for _ in headers) + ' |')
for row in rows[1:]:
lines.append('| ' + ' | '.join(row) + ' |')
print('\n'.join(lines))
# → | name | age | city |
# → | --- | --- | --- |
# → | Alice | 30 | Berlin |
# → | Bob | 25 | Tokyo |
# With pandas (one-liner)
import pandas as pd
df = pd.read_csv(io.StringIO(csv_string))
print(df.to_markdown(index=False))package main
import (
"encoding/csv"
"fmt"
"strings"
)
func main() {
input := "name,age,city\nAlice,30,Berlin\nBob,25,Tokyo"
r := csv.NewReader(strings.NewReader(input))
records, _ := r.ReadAll()
headers := records[0]
var lines []string
lines = append(lines, "| "+strings.Join(headers, " | ")+" |")
sep := make([]string, len(headers))
for i := range sep {
sep[i] = "---"
}
lines = append(lines, "| "+strings.Join(sep, " | ")+" |")
for _, row := range records[1:] {
lines = append(lines, "| "+strings.Join(row, " | ")+" |")
}
fmt.Println(strings.Join(lines, "\n"))
// → | name | age | city |
// → | --- | --- | --- |
// → | Alice | 30 | Berlin |
// → | Bob | 25 | Tokyo |
}# Using Miller (mlr) — convert CSV to Markdown table mlr --icsv --omarkdown cat data.csv # → | name | age | city | # → | --- | --- | --- | # → | Alice | 30 | Berlin | # Using csvtomd (pip install csvtomd) csvtomd data.csv # Using pandas in a one-liner python3 -c " import pandas as pd, sys print(pd.read_csv(sys.argv[1]).to_markdown(index=False)) " data.csv