Sed ведет себя странно при замене концов строк в WSL - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь использовать sed для добавления текста в конце каждой строки для всех файлов .txt в каталоге. Это именно та команда, которую я использую: find . -name "*.txt" -exec sed -i 's/$/:orig/' {} +

Ожидается:

https://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg:orig
https://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg:orig
https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig

Это также то, что я получаю, когда запускаю ее на своем ноутбуке с Linux Mint 19.2. Но когда я пытаюсь сделать это в моем Windows P C, используя sed через Ubuntu в WSL, я получаю следующее:

https://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg
:orig
https://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg
:orig
https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig

Если я cat рассматриваю файлы, находящиеся в Терминал Ubuntu, то, что отображается, больше похоже на это (есть какой-то странный пробел, который делает его похожим на столбцы в SO, но обычно они все выглядят довольно хаотично c):

:orig://pbs.twimg.com/media/EUr539_UMAAFqZM.jpg                                                                         :orig://pbs.twimg.com/media/ENTrymcUwAAnd6_.jpg                                                                         https://pbs.twimg.com/media/EIzzcrFUYAAgfUo.jpg:orig

Я понимаю Windows и Linux текст отформатирован по-разному, и, в частности, эта строка заканчивается проблемно c, хотя я не уверен, имеет ли это какое-либо значение здесь.

Может кто-нибудь пролить свет на это поведение? Как заставить команду вести себя последовательно?

1 Ответ

0 голосов
/ 05 апреля 2020

Проблема в том, что ваши файлы заканчиваются на CR LF , но WSL sed использует только LF и конец строки. Вы можете обойти это с помощью трехэтапного процесса, если вы знаете , это CR LF файл стиля:

  • get избавиться от CR ;
  • сделать ваши изменения;
  • положить CR обратно.

Это будет go что-то вроде: sed -i -e 's/\r$//' -e 's/$/:orig/' -e 's/$/\r/'.

Однако, это не будет работать с файлами UNIX, так как первая замена ничего не даст, но третья добавит CR символ в конце каждой строки, хотя изначально его там не было. Если вы хотите что-то, что будет работать с обоими типами файлов, это должно сделать это:

sed -E 's/(\r)?$/:orig\1/'

Это захватывает дополнительный CR в конце строки и помещает его обратно в подстановку (если он не находится в исходной строке, он не вернет его).

...