Powershell에서 GnuWin32/sed의 예기치 않은 동작

Powershell에서 GnuWin32/sed의 예기치 않은 동작

나는 사용하고있다GnuWin32Windows 명령줄의 도구/파워셸.

무엇을 참조하십시오:

 11:15 enlil D:\Users\x> Get-ChildItem .gitconfig  | sed "s/ */ /g"


 D i r e c t o r y : D : \ U s e r s \ x


 M o d e L a s t W r i t e T i m e L e n g t h N a m e
 - - - - - - - - - - - - - - - - - - - - - - - - - - -
 - a - - - 6 / 2 3 / 2 0 1 4 4 : 1 1 P M 5 6 . g i t c o n f i g

내가 기대했던 것:

 11:15 enlil D:\Users\x> ls .gitconfig  | sed "s/ */ /g"


 Directory: D:\Users\x


 Mode LastWriteTime Length Name
 ---- ------------- ------ ----
 -a--- 6/23/2014 4:11 PM 56 .gitconfig

나의 목표PowerShell에서 추가한 데이터 열 사이의 중복 공백을 제거하는 것입니다. 재미있는 점은 이것이 한 컴퓨터(Win8.1 포함)에서는 완벽하게 작동하지만 Win7이 설치된 다른 컴퓨터에서는 작동하지 않는다는 것입니다.

그리고 더 간단한 예에서도 작동합니다.

 11:49 enlil D:\Users\x> echo "t  a t" |  sed "s/ */ /g"
 t a t

어떤 도움이라도 대단히 감사하겠습니다.

참고로 -Get-ChildItems의 일반 출력다음과 같습니다:

 11:22 enlil D:\Users\x> ls .gitconfig


    Directory: D:\Users\x


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         6/23/2014   4:11 PM         56 .gitconfig

답변1

유니코드입니다. sed에서 나오는 것은 PowerShell이 ​​유니코드와 ASCII를 구별하는 데 사용하는 2바이트 접두사가 없는 유니코드입니다. 따라서 PowerShell은 이를 ASCII라고 생각하고 \0 바이트(2바이트 유니코드 문자의 상위 바이트)를 공백으로 표시합니다. 그리고 PowerShell은 내부적으로 유니코드를 처리하므로 실제로 모든 원본 바이트를 2바이트 유니코드 문자로 확장합니다. 이는 PowerShell이 ​​유니코드를 허용하도록 강제할 수 있는 방법이 아닙니다. 가능한 방법은 다음과 같습니다.

  1. 유니코드가 SED에 입력으로 제공되나요? 가능성은 낮지만 가능하다고 생각합니다. 확인해 보세요.

  2. SED의 출력이 유니코드 표시기 \uFEFF로 시작되도록 합니다. 이는 아마도 SED 소스 코드에서 누락된 부분일 것입니다.

    _setmode(_fileno(stdout), _O_WTEXT); // probably present and makes it send Unicode
    wprintf(L"\uFEFF"); // probably missing
    

    SED 명령 내부에 다음과 같은 코드를 추가할 수 있습니다.

    sed "1s/^/\xFF\xFE/;..." # won't work if SED produces Unicode but would work it SED passes Unicode through from its input
    sed "1s/^/\uFEFF/;..." # use if SED produces Unicode itself, hopefully SED supports \u
    
  3. sed의 출력을 파일에 쓴 다음 Get-Content -Encoding Unicode를 사용하여 읽습니다. 파일로의 전환은 다음과 같이 cmd.exe 내부 명령을 통해 수행되어야 합니다.

    cmd /c "sed ... >file"
    

    >file을 PowerShell에서 처리하도록 하면 같은 방식으로 엉망이 됩니다.

  4. PowerShell의 결과 텍스트에서 \0 문자를 삭제합니다. 이는 코드 0xA 또는 0xD를 포함하는 유니코드 바이트를 생성하는 국제 문자에서는 제대로 작동하지 않습니다. 대신 줄 분할이 발생하게 됩니다.

관련 정보