bcp
저는 Windows 컴퓨터에서 텍스트 파일을 작업하고 있습니다. 유틸리티를 사용하여 파일의 데이터를 데이터베이스 테이블에 로드하기 전에 후행 탭 문자를 제거해야 합니다.
Bash 스크립트의 다음 명령은 후행 탭을 제거합니다.
sed 's/[\t]*$//' < ./input/raw.txt >> ./input/data.txt
하지만 CR
- LF
명령이 실패한 이유 로 변환됩니다 LF
.bcp
유지하려는 노력의 일환으로 다음 CR
을 LF
시도했습니다.
sed 's/[\t]*$/$CR/' < ./input/raw.txt >> ./input/data.txt
그러나 결과는 다음과 같습니다.
원하는 결과는 다음과 같습니다.
원하는 출력을 얻으려면 명령을 어떻게 수정해야 합니까?
답변1
이 패키지를 설치해야 합니다 unix2dos
. 여기에는 두 가지 유틸리티가 있습니다.
unix2dos Convert UNIX newlines to CR-LF
dos2unix Convert DOS CR-LF to UNIX newlines
5개 줄이 포함된 테스트 파일을 만들고 16진수 덤프를 수행하여 줄 끝을 확인하겠습니다.
$ jot -w 'line %d' 5 > foo
$ hexdump -C foo
00000000 6c 69 6e 65 20 31 0a 6c 69 6e 65 20 32 0a 6c 69 |line 1.line 2.li|
00000010 6e 65 20 33 0a 6c 69 6e 65 20 34 0a 6c 69 6e 65 |ne 3.line 4.line|
00000020 20 35 0a | 5.|
00000023
각 줄은 개행 문자(hex 0a)로 끝나는 것을 볼 수 있습니다.
이제 이러한 개행을 DOS CR-LF 줄 끝으로 변환하고 다시 확인합니다.
$ unix2dos foo
$ hexdump -C foo
00000000 6c 69 6e 65 20 31 0d 0a 6c 69 6e 65 20 32 0d 0a |line 1..line 2..|
00000010 6c 69 6e 65 20 33 0d 0a 6c 69 6e 65 20 34 0d 0a |line 3..line 4..|
00000020 6c 69 6e 65 20 35 0d 0a |line 5..|
00000028
이제 각 줄은 CR-LF, hex 0d 0a로 끝납니다.
마지막으로 파일을 원래 UNIX 개행 문자로 다시 변환할 수 있습니다.
$ dos2unix foo
$ hexdump -C foo
00000000 6c 69 6e 65 20 31 0a 6c 69 6e 65 20 32 0a 6c 69 |line 1.line 2.li|
00000010 6e 65 20 33 0a 6c 69 6e 65 20 34 0a 6c 69 6e 65 |ne 3.line 4.line|
00000020 20 35 0a | 5.|
00000023
답변2
표준에서는 sed
줄 끝에 있는 sed 's/[\t]*$//'
모든 백슬래시와 문자가 제거됩니다. GNU 구현은 t
해당 환경에 sed
변수가 존재하는 경우에만 이를 수행합니다 .POSIXLY_CORRECT
sed 's/\t*$//'
지정되지 않았지만 적어도 GNU의 경우 sed
환경 여부에 관계없이 후행 TAB이 제거됩니다.POSIXLY_CORRECT
여기에서 다음을 수행할 수 있습니다.
sed $'s/\t*$/\r/'
각각 TAB 및 CR과 같거나 확장되는 ksh93 $'...'
스타일 인용을 사용하세요. 이는 이제 다른 많은 쉘에서 지원되며 POSIX 표준의 다음 버전에 나타날 것입니다 .\t
\r
sh
쉘 변수에 TAB 및 CR 문자가 있는 경우 다음 문자를 사용할 필요가 없습니다. $'...'
예:
eval "$(printf 'TAB="\t" CR="\r"')"
다음을 수행할 수 있습니다.
sed "s/$TAB*\$/$CR/"
단, 큰따옴표로 묶어야 합니다. 작은따옴표 내에서는 확장이 수행되지 않습니다.
이제 입력이 LF 문자로 끝나지 않는 경우(Unix에서는 유효하지 않은 텍스트가 됨) 해당 문자( sed
적어도 GNU의 경우)는 CR 문자로 끝나는 파일을 생성하여 Unix에서 유효하지 않게 만듭니다. DOS에서도 마찬가지입니다.
Unix에서 DOS로 텍스트 파일을 변환하려면 이 유틸리티를 사용할 수 있으며 unix2dos
문제가 없습니다.
sed $'s/\t*$//' | unix2dos
또는 다음 패턴을 사용 perl
하십시오 sed
.
perl -pe 's/\t*$//; s/\n/\r\n/'
perl -p
라인 구분 기호를 포함하는 전체 라인이 있는 패턴 공간( 거기) sed
을 제외하고 각 입력 라인에 대해 코드를 실행하는 것처럼 작동합니다 . 또한 , , 이스케이프 문자를 지원하며(표준은 정규 표현식에서만 및 만 지원 ) 텍스트가 아닌 파일을 처리할 수 있습니다.perl
$_
\t
\n
\r
sed
\n
답변3
사용행복하다(이전 Perl_6)
~$ cat unix2dos.raku
my $fh1 = open $*IN, :r;
#below :x opens write-only :exclusive (i.e. 'no-clobber')
my $fh2 = open $*OUT, :x, nl-out => "\r\n";
for $fh1.lines() { $fh2.put($_) };
$fh1.close;
$fh2.close;
Raku(Perl6이라고도 함)는 Perl 계열의 프로그래밍 언어입니다. Perl6 프로젝트가 시도하는 것 중 하나는 코드의 이식성을 높이기 위해 운영 체제 관련 문제를 추상화하는 것이며 이러한 문제 중 하나는 개행 처리입니다. Raku는 nl-in
파일 핸들 입력에 대한 인수(기본값은 ["\x0A", "\r\n"]
)를 제공합니다. 기본적으로 \n
-를 사용하여 줄 바꿈을 종료하기 위해 내부적으로 줄을 자동으로 자르고 nl-out
파일 핸들 출력에 대한 인수를 제공합니다(기본값은 "\n"
).
OP의 핵심 진술은 다음과 같습니다.
...그러나 이는 bcp 명령이 실패하게 만드는
CR-LF
것으로 해석됩니다 .LF
따라서 위의 Raku 스크립트의 경우(사용 중인 플랫폼에 관계없이) 쓰기 위해 파일을 열고 줄 nl-out => \r\n
바꿈이 CRLF임을 설정할 수 있습니다. Raku는 느리게 읽으 lines
므로 이 스크립트는 메모리를 절약해야 합니다. 위 스크립트를 실행 가능하게 만들지 않고도 다음과 같이 명령줄에서 호출할 수 있습니다.
~$ raku unix2dos.raku < ends_with_LF.txt > ends_with_CRLF.txt
위 스크립트는 기본적으로 $*IN
stdin이므로 "일회용"이지만 Raku는 읽기 $*ARGFILES
및 디렉토리 기능도 제공합니다. dir
마지막으로 아래 첫 번째 링크는 Raku의 개행 처리에 대한 훌륭한 요약을 제공합니다.