파워셸을 사용하여 CRLF 교체
편집자 참고: OP의 이후 논평으로 판단할 때, 이 질문의 요지는 다음과 같습니다.PowerShell에서 CRLF(윈도우즈 스타일) 줄 끝이 있는 파일을 LF 전용(유닉스 스타일) 파일로 변환하려면 어떻게 해야 합니까?
파워셸 스크립트는 다음과 같습니다.
$original_file ='C:\Users\abc\Desktop\File\abc.txt'
(Get-Content $original_file) | Foreach-Object {
$_ -replace "'", "2"`
-replace '2', '3'`
-replace '1', '7'`
-replace '9', ''`
-replace "`r`n",'`n'
} | Set-Content "C:\Users\abc\Desktop\File\abc.txt" -Force
이 코드를 사용하면 2를 3으로, 1을 7로, 9를 빈 문자열로 바꿀 수 있습니다.캐리지 리턴 라인 피드를 라인 피드로만 교체할 수 없습니다.하지만 이것은 효과가 없습니다.
다음은 Windows PowerShell v5.1 / PowerShell Core v6.2.0의 최신 답변입니다.
Andrew Savinh의 불운한 답변은, 받아들여졌음에도 불구하고, 이 글에서 근본적으로 결함이 있습니다(나는 그것이 고쳐지기를 바랍니다 - 댓글과 편집 내역에 그렇게 하기에 충분한 정보가 있습니다).
Ansgar Wiecher의 유용한 답변은 잘 작동하지만 직접적인 사용이 필요합니다.NET Framework(변경될 수 있지만 전체 파일을 메모리로 읽습니다.)의 직접 사용.NET Framework는 그 자체로는 문제가 되지 않지만 초보자에게는 마스터하기 어렵고 일반적으로 기억하기 어렵습니다.
PowerShell Core의 미래 버전에는 다음과 같은 기능이 도입될 수 있습니다.
Convert-TextFile
께-LineEnding
특정 새 줄 스타일로 텍스트 파일을 인플레이스 업데이트할 수 있는 매개 변수: GitHub 이슈 #6201을 참조하십시오.
PSv5+에서는 이제 PowerShell 네이티브 솔루션이 가능합니다. 다음과 같습니다.Set-Content
에서는 이를지니다를 합니다.-NoNewline
스위치 - 플랫폼 네이티브 새[1] 라인의 원치 않는 추가를 방지합니다.
# Convert CRLFs to LFs only.
# Note:
# * (...) around Get-Content ensures that $file is read *in full*
# up front, so that it is possible to write back the transformed content
# to the same file.
# * + "`n" ensures that the file has a *trailing LF*, which Unix platforms
# expect.
((Get-Content $file) -join "`n") + "`n" | Set-Content -NoNewline $file
위 사항은 다음에 의존합니다.Get-Content
CR 전용, CRLF 및 LF 전용 새 줄을 조합하여 사용하는 텍스트 파일을 한 줄씩 읽는 기능.
주의사항:
입력 파일을 동일한 인코딩으로 다시 만들려면 입력 파일과 일치하도록 출력 인코딩을 지정해야 합니다.위의 명령은 출력 인코딩을 지정하지 않습니다. 지정하려면 ;을 사용하십시오.
기본적으로, 사용하지 않음
-Encoding
:Windows PowerShell에서는 미국 영어 시스템의 Windows-1252와 같이 시스템의 단일 바이트 8비트 레거시 인코딩인 "ANSI" 인코딩을 사용할 수 있습니다.
PowerShell(코어) v6+에서는 BOM 없이 UTF-8 인코딩을 얻을 수 있습니다.
입력 파일의 내용과 변환된 복사본은 메모리에 전체적으로 들어맞아야 합니다. 이는 큰 입력 파일에서는 문제가 될 수 있지만 텍스트 파일에서는 거의 문제가 되지 않습니다.
입력 파일에 다시 쓰는 프로세스가 중단되면 파일이 손상될 위험이 적습니다.
사실 쓸 줄이 여러 개라면-NoNewline
또한 두 줄 사이에 새 줄을 배치하지 않습니다. 그러나 현재의 경우 문자열이 하나만 작성되므로 이는 관련이 없습니다.
버전을 지정하지 않았습니다. Powershell v3를 사용하고 있는 것 같습니다.
사용해 보십시오.
$path = "C:\Users\abc\Desktop\File\abc.txt"
(Get-Content $path -Raw).Replace("`r`n","`n") | Set-Content $path -Force
편집자 참고 사항:mikez가 설명에서 지적했듯이, 에서는 원하지 않는 후행 CRLF를 추가합니다.확인 방법:'hi' > t.txt; (Get-Content -Raw t.txt).Replace("`r`n","`n") | Set-Content t.txt; (Get-Content -Raw t.txt).EndsWith("`r`n")
어느 쪽이 산출하는지$True
.
이렇게 하면 전체 파일이 메모리에 로드되므로 대용량 파일을 처리하려는 경우 다른 솔루션이 필요할 수 있습니다.
갱신하다
v2에 대해 작동할 수 있습니다(테스트할 곳이 없습니다).
$in = "C:\Users\abc\Desktop\File\abc.txt"
$out = "C:\Users\abc\Desktop\File\abc-out.txt"
(Get-Content $in) -join "`n" > $out
편집자 참고 사항:이 솔루션은 (지금은) 다른 파일에 쓰기 때문에 (아직 결함이 있는) v3 솔루션과 같지 않습니다.(Ansgar Wiechers가 댓글에서 지적한 함정을 피하기 위해 다른 파일을 사용합니다.>
실행이 시작되기 전에 대상 파일을 잘라냅니다.그러나 더 중요한 것은 이 솔루션도 원치 않을 수 있는 후행 CRLF를 추가한다는 점입니다.사용하여 확인'hi' > t.txt; (Get-Content t.txt) -join "`n" > t.NEW.txt; [io.file]::ReadAllText((Convert-Path t.NEW.txt)).endswith("`r`n")
어느 쪽이 산출하는지$True
.
하지만 메모리에 로드되는 것에 대해서는 같은 예약입니다.
가짜 CR-LF를 추가하지 않는 대체 솔루션:
$original_file ='C:\Users\abc\Desktop\File\abc.txt'
$text = [IO.File]::ReadAllText($original_file) -replace "`r`n", "`n"
[IO.File]::WriteAllText($original_file, $text)
아래는 모든 파일을 재귀적으로 변환하는 나의 스크립트입니다.제외할 폴더 또는 파일을 지정할 수 있습니다.
$excludeFolders = "node_modules|dist|.vs";
$excludeFiles = ".*\.map.*|.*\.zip|.*\.png|.*\.ps1"
Function Dos2Unix {
[CmdletBinding()]
Param([Parameter(ValueFromPipeline)] $fileName)
Write-Host -Nonewline "."
$fileContents = Get-Content -raw $fileName
$containsCrLf = $fileContents | %{$_ -match "\r\n"}
If($containsCrLf -contains $true)
{
Write-Host "`r`nCleaing file: $fileName"
set-content -Nonewline -Encoding utf8 $fileName ($fileContents -replace "`r`n","`n")
}
}
Get-Childitem -File "." -Recurse |
Where-Object {$_.PSParentPath -notmatch $excludeFolders} |
Where-Object {$_.PSPath -notmatch $excludeFiles} |
foreach { $_.PSPath | Dos2Unix }
위의 @ricky89 및 @mklement0의 예를 기반으로 몇 가지 개선 사항을 포함한 다른 버전 추가:
처리할 스크립트:
- 현재 폴더의 *.txt 파일
- LF를 CRLF로 대체(Windows 줄 끝 부분에 대한 유닉스)
- 결과 파일을 CR-to-CRLF 하위 폴더에 저장
- 100MB 이상의 파일, PS v5에서 테스트됨.
LF-CRLF.ps1:
# get current dir
$currentDirectory = Split-Path $MyInvocation.MyCommand.Path -Parent
# create subdir CR-to-CRLF for new files
$outDir = $(Join-Path $currentDirectory "CR-to-CRLF")
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
# get all .txt files
Get-ChildItem $currentDirectory -Force | Where-Object {$_.extension -eq ".txt"} | ForEach-Object {
$file = New-Object System.IO.StreamReader -Arg $_.FullName
# Resulting file will be in CR-to-CRLF subdir
$outstream = [System.IO.StreamWriter] $(Join-Path $outDir $($_.BaseName + $_.Extension))
$count = 0
# read line by line, replace CR with CRLF in each by saving it with $outstream.WriteLine
while ($line = $file.ReadLine()) {
$count += 1
$outstream.WriteLine($line)
}
$file.close()
$outstream.close()
Write-Host ("$_`: " + $count + ' lines processed.')
}
CMD의 경우 한 줄 LF 전용:
powershell -NoProfile -command "((Get-Content 'prueba1.txt') -join \"`n\") + \"`n\" | Set-Content -NoNewline 'prueba1.txt'"
그래서 당신은 .bat를 만들 수 있습니다.
다음은 매우 큰 파일을 빠르게 처리할 수 있습니다.
$file = New-Object System.IO.StreamReader -Arg "file1.txt"
$outstream = [System.IO.StreamWriter] "file2.txt"
$count = 0
while ($line = $file.ReadLine()) {
$count += 1
$s = $line -replace "`n", "`r`n"
$outstream.WriteLine($s)
}
$file.close()
$outstream.close()
Write-Host ([string] $count + ' lines have been processed.')
언급URL : https://stackoverflow.com/questions/19127741/replace-crlf-using-powershell
'programing' 카테고리의 다른 글
Flask Python, 목록을 반환하거나 Ajax 호출에 받아쓰려고 합니다. (0) | 2023.07.27 |
---|---|
GENERATE ALVERS 쿼리의 from_unixtime에 대한 대안 (0) | 2023.07.27 |
MySQL 저장 프로시저에서 커서 오류 발생 (0) | 2023.07.27 |
mariadb 오류 | next cloud 설치 | ERROR 2002 (HY000):소켓 '/run/mysqld/mysqld'를 통해 로컬 서버에 연결할 수 없습니다.양말' (0) | 2023.07.27 |
곡선 경로를 따라 이동하는 보기 또는 이미지를 애니메이션화하려면 어떻게 해야 합니까? (0) | 2023.07.27 |