Команда Windows для преобразования окончаний строк Unix?

Есть ли в Windows команда для преобразования окончаний строк в файле?

У нас есть test.bat, который нам нужно запустить, чтобы запустить наш сервер. Мы используем Perforce, и нам нужно, чтобы в нашей рабочей области были окончания строк unix. По какой-то причине нам не разрешено изменять окончания строк на Windows в наших рабочих областях. Однако сервер работает под управлением Windows.

Каждый раз, когда мне нужно запустить bat-файл, я открываю его в Notepad ++ и выбираю EditEOL convertWindows. Есть ли способ автоматизировать это, чтобы нам не приходилось вручную изменять окончания строк каждый раз, когда мы синхронизируемся с Perforce?

Заранее спасибо.


person Deepti Jain    schedule 10.07.2013    source источник


Ответы (17)


На самом деле это можно сделать очень легко с помощью команды more, которая включена в Windows NT и более поздние версии. Чтобы преобразовать input_filename, содержащий UNIX EOL (конец строки) \n, в output_filename, содержащий Windows EOL \r\n, просто сделайте следующее:

TYPE input_filename | MORE /P > output_filename

У команды more есть дополнительные параметры форматирования, о которых вы, возможно, не знали. Запустите more/?, чтобы узнать, что еще more умеет.

person TampaHaze    schedule 08.01.2015
comment
это по-прежнему отлично работает в Windows 9, спасибо! Возможно, стоит упомянуть, что файл output_filename должен существовать до запуска этой команды, и его содержимое будет перезаписано. - person SCBuergel; 18.12.2015
comment
Кажется, это добавляет дополнительную строку новой строки к файлам, которые не заканчиваются новой строкой, просто заголовком, если это имеет значение для вашего конкретного сценария. - person aolszowka; 17.02.2016
comment
К сожалению, это также сбивает все вкладки с пробелами. - person Colin; 22.12.2016
comment
Мне нужно обратное. любая идея? - person Ross Brigoli; 09.02.2017
comment
Отличный ответ! Чуть проще: more /P <input_file >output_file - person Dimagog; 28.03.2017
comment
@Sebastian Что такое Windows 9? - person MD XF; 10.05.2017
comment
@adrianTNT, вы сделали TYPE input_file | MORE /P > input_file - person Andrew Steitz; 31.08.2017
comment
@AndrewSteitz Он хотел преобразование на месте. - person Franklin Yu; 14.03.2018
comment
@FranklinYu, вы правы. Сначала я был озадачен вашим комментарием, а потом понял, что в своем предыдущем комментарии я забыл? потому что я спрашивал (очень плохо), действительно ли он напечатал это в командной строке. Дох! Я спрашивал (ну, хотел спросить) его, потому что был уверен, что это сработает, и даже попробовал, чтобы быть уверенным на 100%. Пунктуация имеет значение (а я пошутил). Мне нравится пример. Можем ли мы есть, бабушка? vs Можем ли мы съесть бабушку? (1-е, спросите бабушку, можем ли мы поесть. 2-е, спросите кого-нибудь еще, можем ли мы съесть бабушку, LOL). Спасибо, что указали на мою ошибку, чтобы я мог уточнить !!! - person Andrew Steitz; 15.03.2018

Воспользуйтесь утилитой unix2dos. Вы можете загрузить двоичные файлы здесь.

person David Jashi    schedule 10.07.2013
comment
Опять же, это просто альтернатива блокноту ++. На самом деле не получится автоматизировать это. Мне придется запустить этот инструмент. Я меняю окончание строк в блокноте ++ на данный момент. - person Deepti Jain; 11.07.2013
comment
Это инструмент командной строки. И он больше подходит для автоматизации, чем инструменты с графическим интерфейсом. Вы можете написать периодическое at задание, которое фильтрует все файлы в какой-либо папке, в которую вы помещаете свои командные файлы. Все зависит от того, что вы имеете в виду под автоматизацией. - person David Jashi; 11.07.2013

Я имел дело с CRLF проблемами, поэтому решил создать действительно простой инструмент для преобразования (на NodeJS):

Это интерфейс командной строки конвертера EOL для NodeJS

Итак, если у вас установлен NodeJS с npm, вы можете попробовать:

npm i -g eol-converter-cli
eolConverter crlf "**/*.{txt,js,java,etc}"

Путь можно настроить динамически с помощью регулярного выражения Glob (такое же регулярное выражение, как в оболочке).

Так что, если вы можете использовать NodeJS, это действительно просто, и вы можете интегрировать эту команду для преобразования всего рабочего пространства в желаемые окончания строк.

person Jurosh    schedule 28.06.2017
comment
Похоже, ваше решение попало в - person Mikhail; 13.08.2017

Вы можете сделать это без дополнительных инструментов в VBScript:

Do Until WScript.StdIn.AtEndOfStream
  WScript.StdOut.WriteLine WScript.StdIn.ReadLine
Loop

Поместите указанные выше строки в файл unix2dos.vbs и запустите его следующим образом:

cscript //NoLogo unix2dos.vbs <C:\path\to\input.txt >C:\path\to\output.txt

или вот так:

type C:\path\to\input.txt | cscript //NoLogo unix2dos.vbs >C:\path\to\output.txt

Вы также можете сделать это в PowerShell:

(Get-Content "C:\path\to\input.txt") -replace "`n", "`r`n" |
  Set-Content "C:\path\to\output.txt"

который можно еще упростить до следующего:

(Get-Content "C:\path\to\input.txt") | Set-Content "C:\path\to\output.txt"

Вышеупомянутый оператор работает без явной замены, потому что Get-Content неявно разделяет входные файлы при любом типе разрыва строки (CR, LF и CR-LF), а Set-Content присоединяет входной массив с разрывами строк Windows (CR-LF) перед записью его в файл.

person Ansgar Wiechers    schedule 10.07.2013

Windows MORE ненадежен, он неизбежно уничтожает табуляторы и добавляет строки.

unix2dos также является частью MinGW / MSYS, Cygutils, GnuWin32 и других коллекций двоичных портов unix - и, возможно, уже быть установлен.

Когда есть python, этот однострочный преобразователь преобразует любые окончания строк в текущую платформу - на любая платформа:

TYPE UNIXFILE.EXT | python -c "import sys; sys.stdout.write(sys.stdin.read())" > MYPLATFILE.EXT

or

python -c "import sys; sys.stdout.write(open(sys.argv[1]).read())" UNIXFILE.EXT > MYPLATFILE.EXT

Или поместите однострочник в сценарий .bat / shell и в PATH в соответствии с вашей платформой:

@REM This is any2here.bat
python -c "import sys; sys.stdout.write(open(sys.argv[1]).read())" %1

и используйте этот инструмент, например

any2here UNIXFILE.EXT > MYPLATFILE.EXT
person kxr    schedule 26.02.2016

Основываясь на полезных ответах TampaHaze и MD XF.

Это изменит все файлы .txt на месте в текущем каталоге с LF на CRLF в командной строке.

for /f %f in ('dir /b "*.txt"') do ( type %f | more /p > %f.1 & move %f.1 %f )

Если вы не хотите проверять каждое изменение

переехать

To

движение / г

Чтобы включить изменение подкаталогов

dir / b

To

dir / b / s

Чтобы сделать все это в пакетном файле, включая подкаталоги, без запроса использования ниже

@echo off
setlocal enabledelayedexpansion

for /f %%f in ('dir /s /b "*.txt"') do (
    type %%f | more /p > %%f.1 
    move /y %%f.1 %%f > nul
    @echo Changing LF-^>CRLF in File %%f
)
echo.
pause
person uosjead    schedule 03.05.2018
comment
Нет, это полностью не работает, если в пути к файлу есть место, например, C: \ Program Files \ FileMaker \ FileMaker Server \ HTTPServer \ conf \. - person John Smith; 21.07.2021

попробуй это:

(for /f "delims=" %i in (file.unix) do @echo %i)>file.dos

Протокол сеанса:

C:\TEST>xxd -g1 file.unix
0000000: 36 31 36 38 39 36 32 39 33 30 38 31 30 38 36 35  6168962930810865
0000010: 0a 34 38 36 38 39 37 34 36 33 32 36 31 38 31 39  .486897463261819
0000020: 37 0a 37 32 30 30 31 33 37 33 39 31 39 32 38 35  7.72001373919285
0000030: 34 37 0a 35 30 32 32 38 31 35 37 33 32 30 32 30  47.5022815732020
0000040: 35 32 34 0a                                      524.

C:\TEST>(for /f "delims=" %i in (file.unix) do @echo %i)>file.dos

C:\TEST>xxd -g1 file.dos
0000000: 36 31 36 38 39 36 32 39 33 30 38 31 30 38 36 35  6168962930810865
0000010: 0d 0a 34 38 36 38 39 37 34 36 33 32 36 31 38 31  ..48689746326181
0000020: 39 37 0d 0a 37 32 30 30 31 33 37 33 39 31 39 32  97..720013739192
0000030: 38 35 34 37 0d 0a 35 30 32 32 38 31 35 37 33 32  8547..5022815732
0000040: 30 32 30 35 32 34 0d 0a                          020524..
person Endoro    schedule 10.07.2013
comment
Это работает, но, похоже, удаляет все пустые строки из файла. :( - person MarioVilas; 10.01.2014
comment
@MarioVilas да, ты прав. Для этого можно использовать flip. - person Endoro; 11.01.2014

Мой вклад в это, преобразование нескольких файлов в папку: for %%z in (*.txt) do (for /f "delims=" %%i in (%%z) do @echo %%i)>%%z.tmp

person Ricardo    schedule 07.11.2013

Вы можете создать простой пакетный скрипт, который сделает это за вас:

TYPE %1 | MORE /P >%1.1
MOVE %1.1 %1

Затем запустите <batch script name> <FILE>, и <FILE> будет немедленно преобразован в окончания строки DOS.

person MD XF    schedule 10.05.2017

Я клонировал свой проект git, используя git bash на windows. Все файлы тогда имели LF окончания. В нашем репозитории по умолчанию CRLF окончания.

Я удалил проект, а затем снова клонировал его с помощью Windows Command Prompt. Концовки CRLF тогда остались нетронутыми. В моем случае, если бы я изменил концовку проекта, это привело бы к огромной фиксации и доставило бы проблемы моим товарищам по команде. Итак, сделал это так. Надеюсь, это кому-то поможет.

person retr0    schedule 22.08.2018
comment
Есть способ использовать git для преобразования CRLF в LF. Я просто использовал ваш подход, чтобы получить окончание LF, но я не могу заставить его работать. поэтому я решил изменить конфигурации git, вот фрагмент: $ git config --global core.autocrlf input - person Ziumper; 30.07.2019

Если у вас есть bash (например, git bash), вы можете использовать следующий скрипт для преобразования из unix2dos:

ex filename.ext <<EOF
:set fileformat=dos
:wq
EOF

аналогично, чтобы преобразовать из dos2unix:

ex filename.ext <<EOF
:set fileformat=unix
:wq
EOF
person Stephen Quan    schedule 03.10.2019

Вот простой файл unix2dos.bat, который сохраняет пустые строки и восклицательные знаки:

@echo off
setlocal DisableDelayedExpansion
for /f "tokens=1,* delims=:" %%k in ('findstr /n "^" %1') do echo.%%l

Вывод будет стандартным, поэтому при желании перенаправьте вывод unix2dos.bat в файл.

Он позволяет избежать ошибок других ранее предложенных решений для / f пакетного цикла:
1) Работает с отключением отложенного раскрытия, чтобы избежать съедания восклицательных знаков.
2) Использование самого токенизатора for / f для удаления строки число из findstr /n строк вывода.
(Использование findstr / n необходимо также для получения пустых строк: они будут отброшены, если для / f читать непосредственно из входного файла.)

Но, как отметил Джеб в комментарии ниже, вышеуказанное решение имеет один недостаток, которого нет у других: оно отбрасывает двоеточия в начале строк.

Итак, обновление 2020-04-06 просто для удовольствия, вот еще один однострочный файл на основе findstr.exe, который, похоже, отлично работает без указанных выше недостатков:

@echo off
setlocal DisableDelayedExpansion
for /f "tokens=* delims=0123456789" %%l in ('findstr /n "^" %1') do echo%%l

Дополнительные приемы:
3) Используйте цифры 0–9 в качестве разделителей, чтобы tokens=* пропускал начальный номер строки.
4) Используйте двоеточие, вставленное через findstr /n после номера строки, в качестве разделителя токенов после эхо-команда.

Я оставлю это Джебу, чтобы он объяснил, есть ли крайние случаи, когда echo:something может выйти из строя :-)
Все, что я могу сказать, это то, что эта последняя версия успешно восстановила окончания строк на моем огромном batch library, поэтому исключения, если таковые имеются, должны быть довольно редкими!

person Jean-François Larvoire    schedule 23.01.2020
comment
Это удаляет все двоеточия : с начала строки. Это уничтожает все пакетные функции. Кстати. Протестируйте преобразование файла со строкой типа \..\..\windows\system32\calc.exe. Чтобы решить эту проблему, посмотрите это объяснение - person jeb; 23.01.2020
comment
Ты прав! Я хотел сделать однострочник, проще и лучше, чем ранее опубликованные решения, но, видимо, это невозможно. Пока что ваш единственный правильный. - person Jean-François Larvoire; 07.04.2020
comment
Но проблема была непреодолимой, и, возможно, я нашел еще одно однострочное решение, как показано в отредактированном тексте выше :-) - person Jean-François Larvoire; 07.04.2020
comment
И снова вы потерпели неудачу :-) Попробуйте с ..\..\..\..\..\windows\system32\calc.exe. Единственная безопасная форма ECHO - это echo(. Возможно использование одного лайнера, но я полагаю, что это сложно. - person jeb; 05.10.2020
comment
Caramba, schon wieder verpaßt! Хорошо, я сдаюсь сейчас. Но я уверен, что однажды я справлюсь! :-) - person Jean-François Larvoire; 08.10.2020
comment
Боже, сколько «если», «и» или «но» требует Windows? Я не могу следить за этим. Я никогда не думал, что самая трудоемкая часть разработки всего настраиваемого представления базы данных PHP будет иметь дело с окончаниями строк после копирования готового проекта на наш сервер. Разве не существует утилиты для Windows, которая могла бы решить эту чрезвычайно распространенную проблему без всей этой головной боли? - person John Smith; 21.07.2021
comment
ОБНОВЛЕНИЕ: сделал это с помощью Notepad ++. - person John Smith; 21.07.2021
comment
@John Smith: Существует множество портов программ unix2dos и dos2unix для Windows, которые легко решают исходную проблему. Подробнее см. Ответ kxr ниже stackoverflow.com/a/35661818/2215591. Здесь, чисто ради искусства, я пытался сделать это с помощью короткого пакетного скрипта Windows. Это очень сложно сделать на таком плохом языке сценариев, если вообще возможно. Но именно эта трудность - вот почему некоторые из нас находят это забавным испытанием. :-) - person Jean-François Larvoire; 22.07.2021

Основываясь на ответе Эндоро, но чтобы сохранить пробелы, попробуйте следующее:

@echo off
setlocal enabledelayedexpansion
(for /f "tokens=* delims=:" %%i in ('findstr /n "^" file.unix') do (
        set line=%%i
        set line=!line:*:=!
        echo(!line!
        ))>file.dos
person Ir Relevant    schedule 08.08.2014
comment
Решение Ir Relevant работает нормально, за исключением того, что в нем не отображается восклицательный знак (!). - person mgcoder; 03.03.2015

Поздно, но все еще нет правильного ответа с использованием цикла FOR /F.
(Но вам вообще не нужен цикл FOR, решение от @TampaHaze тоже работает и намного проще)

У ответа от @IR related есть некоторые недостатки.
Он удаляет восклицательные знаки, а также может отбрасывать символы вставки.

@echo off
(
    setlocal Disabledelayedexpansion
    for /f "tokens=* delims=" %%L in ('findstr /n "^" "%~1"') do (
        set "line=%%L"
        setlocal enabledelayedexpansion
        set "line=!line:*:=!"
        (echo(!line!)
        endlocal
    )
) > file.dos

Уловка состоит в том, чтобы использовать findstr /n для префикса каждой строки с <line number>:, это позволяет избежать пропуска пустых строк или строк, начинающихся с ;.
Чтобы удалить <number>: параметр FOR "tokens=1,* delims=:" нельзя использовать, потому что это приведет к удалению всех начальных двоеточий в линия тоже.

Поэтому номер строки удаляется с помощью set "line=!line:*:=!", для этого требуется EnableDelayedExpansion.
Но с EnableDelayedExpansion в строке set "line=%%L" будут удалены все восклицательные знаки, а также символы вставки (только если в строке есть восклицательные знаки).

Вот почему я отключил отложенное расширение раньше и включил его только для двух строк, где это необходимо.

(echo(!line!) выглядит странно, но имеет то преимущество, что echo( может отображать любой контент в !line!, а внешняя скобка позволяет избежать случайных пробелов в конце строки.

person jeb    schedule 23.01.2020

Для преобразования UNIX (LF) в Windows (CR-LF) используйте следующую команду на вашем терминале Windows.

type file.txt > new_file.txt
person jovib    schedule 04.09.2019

Я прохожу курс AWS, и мне часто приходилось копировать текстовые поля в веб-формах AWS в Блокнот Windows. Таким образом, я получаю текст с разделителями LF только в моем буфере обмена. Я случайно обнаружил, что вставив его в мой редактор Delphi, а затем нажав Ctrl + K + W, я запишу текст в файл с разделителями CR + LF. (Готов поспорить, что многие другие редакторы IDE поступили бы так же).

person RHenningsgard    schedule 12.04.2019

Вставка возвратов каретки в Текстовый файл

@echo off
set SourceFile=%1 rem c:\test\test.txt
set TargetFile=%2 rem c:\test\out.txt

if exist "%TargetFile%" del "%TargetFile%"
for /F "delims=" %%a in ('type "%SourceFile%"') do call :Sub %%a
rem notepad "%TargetFile%"
goto :eof


:Sub
echo %1 >> "%TargetFile%"
if "%2"=="" goto :eof
shift
goto sub
person Jimmy Smith    schedule 10.07.2013
comment
На самом деле, это сработало бы, если бы он просто использовал что-то вроде (for /f "tokens=*" %%a in (%~1) do @echo.%%a)>"%~2". - person Ansgar Wiechers; 11.07.2013
comment
@AnsgarWiechers. Да, этот set TargetFile=%2 rem c:\test\out.txt тоже нуждается в улучшении. И, кстати, твой "tokens=*" тоже. - person Endoro; 11.07.2013
comment
@Endoro REM - это комментарий в пакетном файле, вы можете вынуть% 1 rem и затем передать ему нужный файл. Поскольку я предоставил ссылку, я не чувствовал необходимости в дальнейшем документировании, поскольку вы уже работали с командным файлом, верно? Пожалуйста, протестируйте его, так как он действительно работает, и его можно по желанию интегрировать в ваши существующие командные файлы. Спасибо! - person Jimmy Smith; 11.07.2013
comment
У меня отлично работает в Windows 7. Я создал файл c: \ test \ test.txt с EOL из Unix в Notepad ++. После этого я просто запустил командный файл. Опять же, это не мой код, это код, который я немного изменил, чтобы не отображать Блокнот? Я могу показать OP, как заставить его работать, в отличие от последнего комментария. - person Jimmy Smith; 11.07.2013