一部のテキストファイルがLinuxモードで保持されるようにするコマンドを定期的に実行する必要があります。残念ながらdos2unix
、ファイルは常に変更されます。これにより、ファイルとフォルダーのタイムスタンプが台無しになり、不要な書き込みが発生します。
私が書いたスクリプトはBashにあるので、Bashに基づいた回答を好むでしょう。
一部のテキストファイルがLinuxモードで保持されるようにするコマンドを定期的に実行する必要があります。残念ながらdos2unix
、ファイルは常に変更されます。これにより、ファイルとフォルダーのタイムスタンプが台無しになり、不要な書き込みが発生します。
私が書いたスクリプトはBashにあるので、Bashに基づいた回答を好むでしょう。
回答:
dos2unix
フィルタとして使用し、その出力を元のファイルと比較できます。
dos2unix < myfile.txt | cmp -s - myfile.txt
test
によってmyfile.txt
との混同を避けるために、あなたの例では二回/usr/bin/test
。
-s
出力を表示するには、フラグを削除する必要があります。manページから: -s, --quiet, --silent suppress all normal output
目標はただのタイムスタンプへの影響を避けるのであれば、dos2unix
持っている-k
か、--keepdate
同じタイムスタンプを維持するオプションを選択します。一時ファイルを作成して名前を変更するために書き込みを行う必要がありますが、タイムスタンプは影響を受けません。
ファイルの変更が受け入れられない場合は、この回答から次の解決策を使用できます。
find . -not -type d -exec file "{}" ";" | grep CRLF
find ... -exec file ... | grep CRLF
DOSの改行コードを含むファイル(すなわちバイト0D 0A)のために、「あなたのような何かを得るだろう:./1/dos1.txt: ASCII text, with CRLF line terminators
あなたは、これは実際の文字列CRLFが含まれているためで一致している見ることができるようにgrep
探しています単純な文字列CRLF
あなたはgrep
CRLFコード、8進数を試すことができます:
grep -U $'\015' myfile.txt
または16進数:
grep -U $'\x0D' myfile.txt
grep
使用方法、それは私が簡単にディレクトリ内のすべてのこのようなファイルを一覧表示することができますので、grep -lU $'\x0D' *
とに出力を渡しますxargs
。
バージョン以来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
の最初のオカレンスを見たときに終了できます。ノート:
-U
オプション(つまり、-cU
または-qU
)を追加する必要がある場合がありgrep
ます。ファイルがテキストであると考えられる$
場合、正規表現が「正しく」動作するように、正規表現が\r$
!であっても、行末の復帰を無視します。指定すると-U
(または--binary
)この当て推量が無効になりgrep
、ファイルがバイナリとして扱われ、CR終了がそのままの状態でデータが一致するメカニズムに逐語的に渡されます。grep … $'\r\n' myfile.txt
ためです。同じように含む行を探しますかnull文字列、
含む行を探しますかnull文字列、およびすべての行はヌル文字列にマッチします。grep
\n
grep -E 'foo|'
foo
grep $'\r\n'
\r
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
ファイル名ではなく、ファイルタイプのみを出力します。これがないと、名前に文字CRLF
が含まれているファイルが誤検知を引き起こします。file - < filename
でfilename
始まる場合でも動作します-
。
Bashスクリプト:ファイルがテキストファイルかどうかを確認するをご覧ください。file
英語以外のロケールでは、からの出力のチェックが機能しない可能性があることに注意してください。
"$(echo -e '\r')"
、もっと単純なものに置き換えることができます。$'\r'
$'\r\n'
grep $'\r\n'
は私のシステム上のすべてのファイルと一致するようです
grep -U $'\r$'
、grep
行末を推測することを防ぐため、正しい呼び出しはであると思います。
-q
一致するものが見つかった場合-c
は、追加のチェックが必要になる代わりに、戻りコードを設定するだけに使用できます。個人的には2番目のソリューションが好きですが、それは気まぐれに大きく依存しており、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
ファイルの内容も変更されません。
-A
猫に。ただしcat -A file | less
、ファイルが大きすぎる場合に使用するのが1つのヒントです。特に長いファイルについては、ファイルの末尾を確認する必要があることは珍しくありません。(q
少なくするために押してください)
あなたのための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
filename
ファイルにWindowsスタイルの行末を持つ1つ以上の行が含まれている場合は印刷し、含まれていない場合は何も印刷しません。^M
がリテラルの復帰文字でなければならないことを除いて、通常はCtrl+にV続けてEnter
(またはCtrl+ VしてからCtrl+ M)と入力して端末に入力します。bashシェルを使用すると、リテラルのキャリッジリターンを$'\r'
(ここに記載)として記述できるため、次のように記述できます。
grep -l $'\r$' filename
他のシェルも同様の機能を提供します。
代わりに別のツールを使用できます。
awk '/\r$/ { exit(1) }' filename
これは、のステータスで終了します1
(設定$?
に1
ファイルを任意のWindowsスタイルの改行コードが含まれている場合)、およびの状態で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スタイルの行末を混在させることができます。ここでは、 Windowsスタイルの行末を持つファイルを検出することを想定しています。
$'\r'
この質問に対する他の回答で述べたように、コマンドラインでbash(および他のいくつかのシェル)でキャリッジリターンをエンコードできます。
使用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
何らかの理由でインストールできない場合にも便利です。