いくつかの学区が私に送ったデータを解析するPerlスクリプトがあります。新しい学校を追加しているが、以前に一度も経験していなかった問題に直面するようになりました。これにより、$line = <INPUT>
1行ではなくファイル全体を食べます。
file
そのファイルを実行すると、UTF-8 Unicode text, with CRLF, CR line terminators
他のすべてのファイルが返されますASCII text, with CRLF line terminators
。 dos2unixで実行しましたが、それでも長い文字列で実行されます。 Emacsで編集しても、^ Mは行末で表示されます。
この行末を使用可能な行末に変換するにはどうすればよいですか?
修正する: ベンダーから行末が別のファイルを送信したが、まだ機能しません。 CRLF、LFとして報告されます。私いくつかのサンプルライン。
私のコードの一部は次のとおりです。
$line = <INPUT> if ($schooldistricts{$schooldistrict}{'header'});
LINE: foreach $line (<INPUT>) {
next LINE unless ($line =~ /\S/);
<do stuff>
}
ファイルに適切に削除されたヘッダーがあります。その後、foreachループから最初の行を正常に読み込みます。それがすべてです。ファイルの残りの部分が空のようです。
$/
設定しようとしましたが、\r\n\n
スクリプトは何もしませんでした。私が試しても同じです\r\n
。行末にどの文字がエンコードされているかを明示的に確認する方法はありますか?
セカンドアップデート:実験的にファイルをExcelにインポートして分割し、タブ区切りのファイルとして保存してみました。サーバーでdos2unixを実行します。 Perlスクリプトは、2行目以降もまだ解析できません。File
今戻ってくださいUTF-8 Unicode text, with CRLF line terminators
。これが正しい行の終わりなので、Unicodeは問題です。 Unicodeは行末を別々にエンコードしますか?
答え1
perl -pi -e 's/\r\n?/\n/g' your-file
mac2unix
or操作と同様に、CR文字(オプションでLFが続きます)をLFに変換しますdos2unix -c mac
。
または:
perl -pi -e 's/\r\n?/\r\n/g' your-file
これがスクリプトで予想されるものである場合は、CRLFに変換します(たとえば、$/
入力レコード区切り文字をに設定するため"\r\n"
)。
答え2
このパイプは、CR文字またはCR / LFシーケンスをLFに変換します。
tr '\r\n' '\n\r' | sed 's/^\r//g' | tr '\r' '\n'
答え3
使用幸せ(以前のPerl_6)
OPが問題がUnicodeベースであると思う場合、RakuはデフォルトでUTF-8を処理するため、Rakuスクリプトを使用すると役に立ちます。
~$ cat dos2unix.raku
my $fh1 = open $*IN, :r;
#below use :w (write-only) or :x (:x write-only :exclusive i.e. 'no-clobber')
my $fh2 = open $*OUT, :x, nl-out => "\n";
for $fh1.lines() { $fh2.put($_) };
$fh1.close;
$fh2.close;
上記のファイルをスクリプト(「dos2unix.raku」など)に保存し、shebang行を追加して実行可能にします。または、コマンドラインから呼び出すだけです。
~$ raku dos2unix.raku < ends_with_CRLF.txt > ends_with_LF.txt
DOS行末の入力例(1行あたり0d 0a
):
~$ jot -w '%d' 5 | raku unix2dos.raku | hexdump -C
00000000 31 0d 0a 32 0d 0a 33 0d 0a 34 0d 0a 35 0d 0a |1..2..3..4..5..|
Unix行末に変換された出力の例(10a
行あたり):
~$ jot -w '%d' 5 | raku unix2dos.raku | raku dos2unix.raku | hexdump -C
00000000 31 0a 32 0a 33 0a 34 0a 35 0a |1.2.3.4.5.|
0000000a
上記は実際のUnix行の終わり(1行あたり0a
)を複製します。
~$ jot -w '%d' 5 | hexdump -C
00000000 31 0a 32 0a 33 0a 34 0a 35 0a |1.2.3.4.5.|
0000000a
上記のスクリプトが機能しない場合、正規表現ソリューションはslurp
edファイルに役立ちます\v
(垂直スペース)。 Rakuは、Raku Regex方言の行境界のUnicode定義を尊重すると主張しています。 https://unicode.org/reports/tr18/#Line_Boundaries。
~$ raku -e 'slurp.subst(:global, / \v /, "\n").chop.put;' file
#OR
~$ raku -e 'slurp.subst(:global, / <+ :Zl + :Zp> /, "\n").chop.put;' file
下の最初のリンクのスクリプトを参照してくださいunix2dos.raku
(つまり、反対の答え)。
引用:
https://unix.stackexchange.com/a/743445/227738
https://docs.raku.org/言語/newline.html
https://raku.org