各LFの前にCRを追加します。

各LFの前にCRを追加します。

bcp私はWindowsコンピュータでテキストファイルを扱っています。ユーティリティを使用してファイルのデータをデータベーステーブルにロードする前に、末尾のタブ文字を削除する必要があります。

Bashスクリプトの次のコマンドは、末尾のタブを削除します。

sed 's/[\t]*$//' < ./input/raw.txt >> ./input/data.txt

ただし、CR-LFコマンドが失敗した理由に変換されますLFbcp

維持しようとする努力の一環として、以下をCR試しLFました。

sed 's/[\t]*$/$CR/' < ./input/raw.txt >> ./input/data.txt

しかし、結果は次のようになります。

ここに画像の説明を入力してください。

必要な結果は次のとおりです。

ここに画像の説明を入力してください。

目的の出力を取得するには、コマンドをどのように変更する必要がありますか?

答え1

このパッケージをインストールする必要がありますunix2dos。これには2つのユーティリティがあります。

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\rsh

シェル変数に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\rsed\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プロジェクトが試みていることの1つは、コードの移植性を高めるためにオペレーティングシステム固有の問題を抽象化することであり、これらの問題の1つは改行です。 Rakuはnl-inファイルハンドル入力の引数(デフォルトは["\x0A", "\r\n"])を提供します。\nデフォルトでは、 - を使用して改行を終了するために自動的に行を切り捨て、ファイルnl-outハンドル出力の引数を指定します(デフォルトは"\n")。

OPの主な声明は次のとおりです。

...しかし、これはbcpコマンドを失敗させるCR-LFと解釈されます。LF

したがって、上記のRakuスクリプトの場合(使用しているプラ​​ットフォームに関係なく)、書き込み用にファイルを開き、改行がnl-out => \r\nCRLFであることを設定できます。 Rakuはゆっくり読み込むlinesので、このスクリプトはメモリを節約する必要があります。上記のスクリプトを実行可能にすることなく、次のようにコマンドラインから呼び出すことができます。

~$ raku unix2dos.raku < ends_with_LF.txt > ends_with_CRLF.txt

上記のスクリプトはデフォルトでは$*INstdinなので、「使い捨て」ですが、Rakuは読み取り機能$*ARGFILESとディレクトリ機能も提供します。dir最後に、下の最初のリンクはRakuの改行処理の素晴らしい要約を提供します。

https://docs.raku.org/言語/newline.html
https://raku.org

関連情報