bashsedgit-bashmsys

Sed is changing the endlines from CRLF to LF


I'm trying to do script to change all occurrences of xpto to abcd in all .java files in windows 10 system. The script is like above and run in git bash:

$find -path './*/*.java' | xargs -i sed -i 's/xpto/abcd/g' {}

But when I got to check the output files, all of them including the files without xpto have changed endlines to LF. I thought I'd run another script to change the endlines to CRLF but in the folder have files with CRLF and LF and they need to keep the original endline.

EDIT 1

For reproduce the problem follow the steps above:

$printf '%s\r\n' 'first xpto' 'second xpto' > crlf.java
$printf '%s\n' 'first xpto' 'second xpto' > lf.java

$find -path './*.java' | xargs -i sed -i 's/xpto/abcd/g' {}

crlf.java and lf.java files will be with lf endlines


Solution

  • This isn't a generic sed problem, but rather specifically an issue with with the msys-based version of sed included with the Git for Windows.

    One can work around it with some extra logic:

    find . -name '*.java' -print0 | while IFS= read -r -d '' file; do
      IFS= read -r first_line <"$file"
      if [[ $first_line = *$'\r' ]]; then
        is_dos=1
      else
        is_dos=
      fi
      sed -i -e 's/xpto/abcd/g' -- "$file"
      (( is_dos )) && unix2dos "$file"
    done