Windows 텍스트를 Linux 형식으로 변환하기

다양한 플랫폼 간 줄 바꿈 변환을 정복하세요.

Page content

Windows와 Linux 간 줄 끝 처리 불일치 시스템은 포맷팅 문제, Git 경고 및 스크립트 실패를 유발합니다.
이 포괄적인 가이드는 감지, 변환 및 예방 전략을 다룹니다.

windows-to-unix 문서 변환
이 훌륭한 이미지는 AI 모델 Flux 1 dev에 의해 생성되었습니다.

줄 끝 차이 이해하기

운영 체제는 텍스트 파일에서 줄의 끝을 표시하기 위해 다른 규칙을 사용하며, 이는 크로스 플랫폼 개발에서 호환성 문제를 일으킵니다:

  • Windows: Carriage Return + Line Feed (\r\n 또는 CRLF, 헥스 0D 0A)
  • Linux/Unix: Line Feed만 (\n 또는 LF, 헥스 0A)
  • Classic Mac OS: Carriage Return만 (\r 또는 CR, 헥스 0D)

이 역사적 차이는 타자기 기계의 메커니즘에서 비롯됩니다. Windows는 DOS에서 CRLF 규칙을 물려받았으며, 이는 종이를 이동하는 Line Feed와 줄의 시작으로 이동하는 Carriage Return을 모두 필요로 했던 전자 타자기와의 호환성을 유지하기 위해 설계되었습니다.

줄 끝 불일치로 인한 일반적인 문제

1. 스크립트 실행 실패

Windows 줄 끝 처리가 있는 Bash 스크립트는 암호화된 오류와 함께 실패합니다:

bash: ./script.sh: /bin/bash^M: bad interpreter: No such file or directory

^M 문자(카리지 리턴)가 shebang 라인에 포함되어 해석기 검색이 실패하게 됩니다.

2. Git 경고 및 diff 노이즈

Linux에서 Windows 파일을 Git에 커밋할 경우 다음과 같은 경고를 보게 됩니다:

warning: CRLF will be replaced by LF in file.txt.
The file will have its original line endings in your working directory

줄 끝만 다른 경우에도 전체 파일이 변경된 것으로 표시되며, 실제 코드 변경 사항을 가려버립니다.

3. 편집기에서의 시각적 오류

카리지 리턴을 자동으로 감지하지 않는 Linux 텍스트 편집기는 줄 끝에 ^M 문자를 표시하며, 이는 파일을 읽고 편집하는 데 어려움을 줍니다. 이는 특히 Hugo 마크다운 파일에서 frontmatter 파싱을 깨뜨릴 수 있습니다.

4. 데이터 처리 문제

텍스트 파일을 파싱하는 스크립트는 카리지 리턴을 추출된 데이터에 포함시킬 수 있으며, 이는 비교 실패 및 데이터 파이프라인에서 예상치 못한 동작을 유발할 수 있습니다.

Windows 줄 끝 감지하기

파일을 변환하기 전에 변환해야 할 파일을 식별하여 불필요한 수정을 피해야 합니다.

방법 1: file 명령어 사용

가장 신뢰할 수 있는 감지 방법입니다:

file content/post/my-post/index.md

출력 예시:

# Windows 줄 끝:
index.md: UTF-8 Unicode text, with CRLF line terminators

# Linux 줄 끝:
index.md: UTF-8 Unicode text

# 혼합 줄 끝 (문제 있음):
index.md: UTF-8 Unicode text, with CRLF, LF line terminators

방법 2: cat 명령어로 시각적 검사

제어 문자 표시:

cat -A filename.txt

Windows 파일은 줄 끝에 ^M$을 표시하고, Linux 파일은 $만 표시합니다.

방법 3: grep 사용

카리지 리턴 검색:

grep -r $'\r' content/post/2025/11/

이 명령어는 지정된 디렉토리 내 CRLF를 포함한 모든 파일을 식별합니다.

방법 4: hexdump 분석

바이트 수준의 세부 검사:

hexdump -C filename.txt | head -n 20

0d 0a (CRLF)와 0a (LF) 시퀀스를 확인합니다.

Windows에서 Linux 형식으로 변환

다양한 도구가 제공하며, 가용성, 기능 및 성능 측면에서 다른 점이 있습니다.

솔루션 1: dos2unix (추천)

줄 끝 변환에 특화된 가장 견고하고 기능이 풍부한 솔루션입니다.

설치

# Ubuntu/Debian
sudo apt install dos2unix

# Red Hat/CentOS/Fedora
sudo yum install dos2unix

# macOS (Homebrew)
brew install dos2unix

# Arch Linux
sudo pacman -S dos2unix

기본 사용법

# 단일 파일 변환 (즉시 수정)
dos2unix filename.txt

# 백업 포함 변환 (bak 파일 생성)
dos2unix -b filename.txt

# 여러 파일 변환
dos2unix file1.txt file2.txt file3.txt

# 와일드카드 사용
dos2unix *.txt
dos2unix content/post/2025/11/*/index.md

고급 옵션

# 드라이 런 - 수정 없이 미리보기
dos2unix --dry-run filename.txt

# 수정 시간 유지
dos2unix -k filename.txt

# 줄 끝이 다를 경우만 변환
dos2unix -f filename.txt

# 재귀적 변환
find . -name "*.md" -exec dos2unix {} \;

# 디렉토리 트리 내 모든 마크다운 파일 변환
find content/post -type f -name "*.md" -exec dos2unix {} \;

Hugo 게시물 일괄 처리:

# 2025년 게시물의 모든 index.md 파일 변환
dos2unix content/post/2025/**/index.md

# 특정 디렉토리 제외하고 모든 마크다운 파일 변환
find content/post -name "*.md" ! -path "*/drafts/*" -exec dos2unix {} \;

솔루션 2: sed 명령어

추가 설치 없이 모든 Unix 시스템에서 사용 가능하지만, 대규모 일괄 처리에서는 효율성이 낮습니다.

# 단일 파일 변환
sed -i 's/\r$//' filename.txt

# 여러 파일 변환 (루프 사용)
for file in content/post/2025/11/*/index.md; do 
    sed -i 's/\r$//' "$file"
done

# 백업 포함 변환
sed -i.bak 's/\r$//' filename.txt

# 재귀적 변환
find . -name "*.txt" -exec sed -i 's/\r$//' {} \;

주의 사항

  • sed -i는 파일을 즉시 수정합니다.
  • macOS에서는 sed -i '' 's/\r$//' filename.txt를 사용합니다.
  • 처리 중 임시 파일을 생성합니다.
  • dos2unix보다 대규모 파일 집합 처리 시 느립니다.

솔루션 3: tr 명령어

데이터 처리 워크플로우에서 유용한 파이프 기반 접근 방식입니다:

# 기본 변환 (출력 리디렉션 필요)
tr -d '\r' < input.txt > output.txt

# 파이프에서 처리 및 변환
cat input.txt | tr -d '\r' | process_data.sh

# 즉시 수정 불가 - 임시 파일 사용
tr -d '\r' < input.txt > temp.txt && mv temp.txt input.txt

장점

  • 모든 Unix 시스템에 제공됨
  • 스트리밍 데이터 처리에 적합
  • 파이프와 잘 통합

단점

  • 즉시 수정 불가
  • 수동 백업 처리 필요
  • 일괄 작업에 불편

솔루션 4: awk 사용

복잡한 텍스트 처리에 대체 옵션입니다:

awk '{sub(/\r$/,"")}1' input.txt > output.txt

# 또는 더 명확하게:
awk 'BEGIN{RS="\r\n"} {print}' input.txt > output.txt

비교 표

도구 즉시 수정 일괄 처리 백업 속도 가용성
dos2unix 빠름 설치 필요
sed 중간 내장
tr 빠름 내장
awk 중간 내장

예방 전략

Windows 줄 끝을 반복적으로 변환하는 것보다 예방하는 것이 더 효율적입니다.

Git 설정

Git을 사용하여 플랫폼 간 줄 끝을 자동으로 정규화합니다.

옵션 1: 저장소 수준 (.gitattributes)

저장소 루트에 .gitattributes 생성:

# 자동으로 텍스트 파일 감지 및 LF로 정규화
* text=auto

# 명시적으로 텍스트 파일 선언
*.md text
*.txt text
*.sh text eol=lf
*.py text eol=lf
*.go text eol=lf
*.js text eol=lf
*.json text eol=lf

# 이진 파일
*.jpg binary
*.png binary
*.pdf binary

이 설정은 플랫폼과 관계없이 일관된 줄 끝을 보장하고 불필요한 변환을 방지합니다.

옵션 2: 글로벌 사용자 설정

모든 저장소에 대한 Git 행동 설정:

# Linux/macOS: 커밋 시 CRLF를 LF로 변환, LF는 그대로 유지
git config --global core.autocrlf input

# Windows: 체크아웃 시 LF를 CRLF로 변환, 커밋 시 CRLF를 LF로 변환
git config --global core.autocrlf true

# 자동 변환 비활성화 ( .gitattributes만 의존)
git config --global core.autocrlf false

추천 설정

  • Linux/macOS 개발자: core.autocrlf input
  • Windows 개발자: core.autocrlf true
  • 모든 프로젝트: .gitattributes를 사용하여 명시적 제어

기존 저장소 정규화

저장소에 이미 혼합 줄 끝이 포함되어 있는 경우:

# Git 인덱스에서 모든 파일 제거
git rm --cached -r .

# 정규화된 줄 끝으로 파일 복원
git reset --hard

# 정규화된 파일 커밋
git add .
git commit -m "Normalize line endings"

편집기 설정

기본적으로 Unix 줄 끝을 사용하도록 텍스트 편집기를 구성합니다.

Visual Studio Code (settings.json)

{
  "files.eol": "\n",
  "files.encoding": "utf8",
  "files.insertFinalNewline": true,
  "files.trimTrailingWhitespace": true
}

필요 시 언어별로 설정:

{
  "[markdown]": {
    "files.eol": "\n"
  }
}

Vim/Neovim (.vimrc)

set fileformat=unix
set fileformats=unix,dos

Emacs (.emacs 또는 init.el)

(setq-default buffer-file-coding-system 'utf-8-unix)

Sublime Text (Preferences.sublime-settings)

{
  "default_line_ending": "unix"
}

JetBrains IDEs (Settings → Editor → Code Style)

  • 줄 구분자: Unix 및 macOS (\n)

EditorConfig

프로젝트 루트에 .editorconfig를 생성하여 크로스 에디터 호환성을 보장합니다:

root = true

[*]
end_of_line = lf
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{sh,bash}]
end_of_line = lf

[*.bat]
end_of_line = crlf

대부분의 현대 에디터는 .editorconfig 설정을 자동으로 존중하여 팀원이 사용하는 다른 에디터 간 일관성을 보장합니다.

자동화 및 스크립팅

개발 워크플로우에 줄 끝 검사를 통합하여 문제를 조기에 발견합니다.

Pre-commit Git Hook

.git/hooks/pre-commit 생성:

#!/bin/bash
# CRLF 줄 끝을 가진 파일 감지

FILES=$(git diff --cached --name-only --diff-filter=ACM)
CRLF_FILES=""

for FILE in $FILES; do
    if file "$FILE" | grep -q "CRLF"; then
        CRLF_FILES="$CRLF_FILES\n  $FILE"
    fi
done

if [ -n "$CRLF_FILES" ]; then
    echo "Error: 다음 파일은 Windows 줄 끝(CRLF)을 사용하고 있습니다:"
    echo -e "$CRLF_FILES"
    echo ""
    echo "다음 명령어로 변환하세요: dos2unix <filename>"
    echo "또는 편집기를 Unix 줄 끝(LF) 사용하도록 구성하세요"
    exit 1
fi

exit 0

실행 가능하게 설정:

chmod +x .git/hooks/pre-commit

CI/CD 검사

CI 파이프라인에 추가 (GitHub Actions 예시):

name: 줄 끝 검사

on: [push, pull_request]

jobs:
  check-line-endings:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: CRLF 줄 끝 검사
        run: |
          if git ls-files | xargs file | grep CRLF; then
            echo "Error: CRLF 줄 끝을 가진 파일이 감지되었습니다"
            exit 1
          fi          

일괄 변환 스크립트

프로젝트 유지보수를 위한 convert-line-endings.sh 생성:

#!/bin/bash
# 프로젝트 내 모든 텍스트 파일을 Unix 줄 끝으로 변환

set -e

EXTENSIONS=("md" "txt" "sh" "py" "go" "js" "json" "yml" "yaml" "toml")

echo "줄 끝을 Unix 형식으로 변환 중..."

for ext in "${EXTENSIONS[@]}"; do
    echo "*.$ext 파일 처리 중..."
    find . -name "*.$ext" ! -path "*/node_modules/*" ! -path "*/.git/*" \
        -exec dos2unix {} \; 2>/dev/null || true
done

echo "변환 완료!"

일반적인 문제 해결

문제 1: 변환 후 스크립트 여전히 실패

증상: dos2unix로 변환한 Bash 스크립트가 여전히 인터프리터 오류를 보입니다.

해결: 파일 인코딩 및 바이트 순서 마크(BOM) 확인:

# 인코딩 확인
file -i script.sh

# BOM이 존재하는 경우 제거
sed -i '1s/^\xEF\xBB\xBF//' script.sh

# shebang 라인 확인
head -n 1 script.sh | od -c

문제 2: 단일 파일에서 혼합 줄 끝

증상: 파일이 CRLF 및 LF 줄 끝을 모두 보입니다.

해결: dos2unix 강제 모드로 정규화:

dos2unix -f filename.txt

또는 더 강력한 sed 사용:

# 먼저 CR 제거, 이후 정규화
sed -i 's/\r//g' filename.txt

문제 3: Git이 여전히 파일을 수정으로 표시

증상: 줄 끝을 변환한 후 Git이 파일을 수정으로 표시하지만, 변경 사항이 보이지 않습니다.

해결: Git 인덱스 새로 고침:

git add -u
git status

# 여전히 표시되는 경우, Git 설정 확인
git config core.autocrlf

# 임시로 autocrlf 비활성화
git config core.autocrlf false
git add -u

문제 4: 변환 후 Hugo 빌드 실패

증상: 줄 끝 변환 후 Hugo가 frontmatter를 파싱하지 못합니다.

해결: 유니코드 BOM 및 frontmatter 구문 확인:

# 마크다운 파일에서 BOM 제거
find content -name "*.md" -exec sed -i '1s/^\xEF\xBB\xBF//' {} \;

# YAML frontmatter 확인
hugo --debug

문제 5: dos2unix 사용 불가

증상: 시스템에 dos2unix가 없고 패키지를 설치할 수 없습니다.

해결: 이동식 쉘 함수 사용:

dos2unix_portable() {
    sed -i.bak 's/\r$//' "$1" && rm "${1}.bak"
}

dos2unix_portable filename.txt

Hugo 사이트를 위한 특별한 사례

Hugo 정적 사이트는 특히 콘텐츠 파일과 구성에 줄 끝 처리에 특별한 고려가 필요합니다.

Hugo 콘텐츠 변환

# 모든 마크다운 콘텐츠 파일 변환
find content -name "*.md" -exec dos2unix {} \;

# 구성 파일 변환
dos2unix config.toml config.yaml

# i18n 번역 파일 변환
find i18n -name "*.yaml" -exec dos2unix {} \;

# 레이아웃 템플릿 변환
find layouts -name "*.html" -exec dos2unix {} \;

frontmatter 처리

YAML frontmatter는 줄 끝 문제에 특히 민감합니다. 일관성을 유지하세요:

# frontmatter를 포함한 파일 확인
for file in content/post/**/index.md; do
    if head -n 1 "$file" | grep -q "^---$"; then
        file "$file"
    fi
done | grep CRLF

Hugo 빌드 스크립트

빌드 및 배포 스크립트는 Unix 줄 끝을 사용해야 합니다:

dos2unix deploy.sh build.sh
chmod +x deploy.sh build.sh

성능 고려 사항

수천 개의 파일이 있는 대규모 프로젝트의 경우 변환 성능이 중요합니다.

벤치마크 비교

1000개의 마크다운 파일 변환:

# dos2unix: 약 2초
time find . -name "*.md" -exec dos2unix {} \;

# sed: 약 8초
time find . -name "*.md" -exec sed -i 's/\r$//' {} \;

# 병렬 dos2unix: 약 0.5초
time find . -name "*.md" -print0 | xargs -0 -P 4 dos2unix

병렬 처리

GNU Parallel 또는 xargs를 사용하여 더 빠른 일괄 변환:

# xargs와 병렬 실행 사용
find . -name "*.md" -print0 | xargs -0 -P 8 dos2unix

# GNU Parallel 사용
find . -name "*.md" | parallel -j 8 dos2unix {}

크로스 플랫폼 개발 최고 실천

문제 발생을 막기 위해 팀 관습을 수립해야 합니다.

1. 저장소 설정 확인 목록

  • .gitattributes에 텍스트 파일 선언 추가
  • 팀 문서에 core.autocrlf 설정
  • .editorconfig 저장소에 포함
  • 검증을 위한 pre-commit 훅 추가
  • README에 줄 끝 정책 문서화

2. 팀 온보딩

새로운 팀원은 다음을 구성해야 합니다:

# 저장소 복제
git clone <repository>
cd <repository>

# Git 구성
git config core.autocrlf input  # Linux/macOS
git config core.autocrlf true   # Windows

# 설정 확인
git config --list | grep autocrlf
cat .gitattributes

3. 코드 리뷰 가이드라인

  • 줄 끝만 변경된 PR 거부
  • git diff --ignore-cr-at-eol을 사용한 리뷰
  • CI/CD에서 줄 끝 검사 활성화

4. 문서화

프로젝트 README에 포함:

## 줄 끝 규칙

이 프로젝트는 모든 텍스트 파일에 Unix 줄 끝(LF)을 사용합니다.

**설정:**

- Linux/macOS: git config core.autocrlf input
- Windows: git config core.autocrlf true

**파일 변환:**
dos2unix filename.txt

.gitattributes에서 파일별 설정을 참조하세요.

관련 Hugo 및 Linux 주제

플랫폼 간 텍스트 파일 작업은 다양한 관련 도구 및 워크플로우를 이해해야 합니다. 보다 깊은 주제를 탐구하기 위한 자료들입니다:

외부 자료

이 문서의 기술 세부 사항 및 최고 실천을 제공한 권위 있는 자료들입니다: