一部のtextファイルがLinuxモードで保持されるようにするコマンドを定期的に実行する必要があります。残念ながらdos2unix
は常にファイルを変更します。これにより、ファイルとフォルダーのタイムスタンプが混乱し、不要な書き込みが発生します。
私が書いたスクリプトはBashで書かれているので、Bashに基づいた回答をお勧めします。
dos2unix
をフィルターとして使用して、その出力を元のファイルと比較できます。
dos2unix < myfile.txt | cmp - myfile.txt
タイムスタンプへの影響を回避することだけが目的の場合、dos2unix
があります -k
または--keepdate
オプションは、タイムスタンプを同じに保ちます。一時ファイルを作成して名前を変更するには、書き込みを行う必要がありますが、タイムスタンプには影響しません。
ファイルの変更が受け入れられない場合は、 this answer から次の解決策を使用できます。
find . -not -type d -exec file "{}" ";" | grep CRLF
あなたはCRLFコードのためにgrep
を試すことができます、8進数:
grep -U $'\015' myfile.txt
または16進数:
grep -U $'\x0D' myfile.txt
バージョン7.1
dos2unixには-i
、--info
オプションで改行に関する情報を取得します。 dos2unix自体を使用して、変換が必要なファイルをテストできます。
例:
dos2unix -ic *.txt | xargs dos2unix
grep
):復帰を含む行を数えます:
[[ $(grep -c $'\r' myfile.txt) -gt 0 ]] && echo dos
で終わるキャリッジリターンである行を数えます。
[[ $(grep -c $'\r$' myfile.txt) -gt 0 ]] && echo dos
これらは通常同等です。行の内部(つまり、最後ではない)での復帰はまれです。
もっと効率的:
grep -q $'\r' myfile.txt && echo dos
これはより効率的です
grep -c
は、パターン全体の出現をカウントするためにファイル全体を読み取る必要があるため、grep -q
は、パターンの最初の出現を検出すると終了できます。メモ:
grep
であるため、上記全体を通して、-U
オプションの追加(つまり、-cU
または-qU
を使用)が必要になる場合があります。ファイルがテキストファイルであるかどうかを推測します。ファイルがテキストであると判断した場合、$
を定期的に作成しようとして、行末の改行を無視します正規表現は「正しく」機能します—正規表現が\r$
!であっても、-U
(または--binary
)を指定すると、この推測が無効になり、grep
は、ファイルをバイナリとして扱い、CR末尾をそのままにして、データをそのまま一致するメカニズムに渡します。grep
はgrep … $'\r\n' myfile.txt
をパターン区切り文字として扱うため、\n
を実行しないでください。 grep -E 'foo|'
がfoo
またはnull文字列を含む行を検索するのと同様に、grep $'\r\n'
は\r
またはnull文字列を含む行を検索し、すべての行がnull文字列と一致します。file
):[[ $(file myfile.txt) =~ CRLF ]] && echo dos
file
は次のように報告するためです。
myfile.txt: UTF-8 Unicode text, with CRLF line terminators
より安全なバリアント:
[[ $(file -b - < myfile.txt) =~ CRLF ]] && echo dos
どこ
file -b
は、ファイルタイプではなくファイルタイプのみを出力します。これがないと、ファイル name に文字CRLF
が含まれていると、誤検知がトリガーされます。file - < filename
はfilename
が-
で始まる場合でも機能します。 Bashスクリプト:ファイルがテキストファイルかどうかを確認する を参照してください。file
からの出力のチェックは、英語以外のロケールでは機能しない可能性があることに注意してください。
cat -A
を使用
$ cat file
hello
hello
このファイルが* NIXシステムで作成された場合、次のように表示されます。
$ cat -A file
hello$
hello$
しかし、このファイルがWindowsで作成された場合、次のように表示されます。
$ cat -A file
hello^M$
hello
^M
はCR
を表し、$
はLF
を表します。 Windowsが最後の行をCRLF
で保存しなかったことに注意してください
これにより、ファイルの内容も変更されません。
あなたのためのbash関数:
# return 0 (true) if first line ends in CR
isDosFile() {
[[ $(head -1 "$1") == *$'\r' ]]
}
次に、次のようなことができます
streamFile () {
if isDosFile /tmp/foo.txt; then
sed 's/\r$//' "$1"
else
cat "$1"
fi
}
streamFile /tmp/foo.txt | process_lines_without_CR
ファイルにDOS/WindowsスタイルのCR-LF行末がある場合、Unixベースのツールを使用してそれを見ると、各行の終わりにCR( '\ r')文字が表示されます。
このコマンド:
grep -l '^M$' filename
ファイルにWindowsスタイルの行末を持つ1つ以上の行が含まれている場合はfilename
を出力し、含まれていない場合は何も出力しません。 ^M
はリテラルの復帰文字でなければならないことを除いて、通常は次のように入力して端末に入力します。 Ctrl+V に続く Enter (または Ctrl+V その後 Ctrl+M)。 bashシェルを使用すると、リテラルキャリッジリターンを$'\r'
( ここに記載 )として記述できるため、次のように記述できます。
grep -l $'\r$' filename
他のシェルも同様の機能を提供します。
代わりに別のツールを使用できます。
awk '/\r$/ { exit(1) }' filename
これは、ファイルにWindowsスタイルの行末が含まれている場合は1
のステータス($?
を1
に設定)で終了し、含まれている場合は0
のステータスで終了します。シェル、if
ステートメントで使用すると便利です([
ブラケット]
がないことに注意してください):
if awk '/\r$/ { exit(1) }' filename ; then
echo filename has Unix-style line endings
else
echo filename has at least one Windows-style line ending
fi
ファイルには、UnixスタイルとWindowsスタイルの行末を混在させることができます。ここでは、anyWindowsスタイルの行末を持つファイルを検出することを想定しています。
file
を使用:
$ file README.md
README.md: ASCII text, with CRLF line terminators
$ dos2unix README.md
dos2unix: converting file README.md to Unix format...
$ file README.md
README.md: ASCII text
私は使用しています
cat -v filename.txt | diff - filename.txt
うまくいくようです。私は出力が少し読みやすいと思います
dos2unix < filename.txt | diff - filename.txt
何らかの理由でdos2unix
をインストールできない場合にも役立ちます。