Powershell v2: заменить CRLF на LF

Используя Powershell v2, вызываемый из пакетного файла, я хочу заменить каждый CRLF в файле просто LF. Если в файле есть только LF без CR, то я хочу, чтобы все LF оставались в покое.

Я не хочу завершающий CRLF в результирующем файле, если это возможно.

Я нашел этот вопрос здесь, в Переполнении стека, которое, похоже, близко соответствует, но не определяет требования к версии Powershell и не определяет другие критерии, описанные выше. Отсюда и этот вопрос.

Принятый ответ на этот вопрос рекомендует этот код:

$in = "C:\Users\abc\Desktop\File\abc.txt"
$out = "C:\Users\abc\Desktop\File\abc-out.txt"
(Get-Content $in) -join "`n" > $out

Я немного изменил его и настроил так, чтобы он работал внутри командного файла, чтобы он читал:

powershell -Command "(Get-Content file1.txt) -join '`n' > file2.txt"

К сожалению, это не работает. Все НЧ преобразуются в строку `n,

Как я могу заставить это работать?

2 ответа

Решение

Те, кто до меня правы, вы должны использовать "`n"

При использовании PowerShell я рекомендую выполнить следующие параметры:
-noninteractive указать, что вы не хотите взаимодействовать с PowerShell
-NoProfile - значительно ускоряет работу (пропускает загрузку профиля)
-ExecutionPolicy Bypass - обходит проблемы безопасности, если вы находитесь в среде компании

Редактировать:

Извините за ошибку, которую вы упомянули. Теперь у меня есть средство тестирования PowerShell 2.0.

Исправил ваш пример (ошибка заключалась в том, что вы должны избегать двойных кавычек из-за их интерпретации powershell.exe). Этот подход не работает полностью, поскольку он оставляет CRLF в конце файла:

powershell.exe -noninteractive -NoProfile -ExecutionPolicy Bypass -Command "& {(Get-Content file_crlf.txt) -join \"`n\" > file_lfonly.txt};"

Однако для совершенно правильного решения требуется другой подход (через класс IO.file):

powershell.exe -noninteractive -NoProfile -ExecutionPolicy Bypass -Command "& {[IO.File]::WriteAllText('file_lfonly.txt', ([IO.File]::ReadAllText('file_crlf.txt') -replace \"`r`n\", \"`n\"))};"

Это полностью преобразует ваш CRLF в LF, Небольшое предупреждение, которое преобразуется в ASCII, а не в Unicode (выходит за рамки этого вопроса).

Все примеры теперь протестированы на PowerShell v2.0.50727.

Пара вещей:

  • Одинарные кавычки ' буквально - используйте двойные кавычки " так что PowerShell знает, что вы имеете в виду новую строку

  • Если вам нужно избежать двойных кавычек в двойных кавычках, используйте "" или "

Редактировать:

Ваш оригинальный пост работал для меня, так что похоже, что он связан с PowerShell 5 v 2, и я не могу проверить решение. Вместо escape-символов, вот решение с использованием scriptblock:

powershell -Command {(Get-Content file1.txt) -join "`n" > file2.txt}

Стоит отметить, что в Notepad++ это тривиально и может быть сделано для нескольких файлов одновременно:

Новая строка заменена в Notepad

Другие вопросы по тегам