web-dev-qa-db-ja.com

BashスクリプトでDOS/Windowsのニューライン(CRLF)をUnixのニューライン(LF)に変換する方法?

プログラムで(つまりviを使用しないで)DOS/Windows改行をUnixに変換する方法を教えてください。

dos2unixおよびunix2dosコマンドは特定のシステムでは利用できません。 sed/awk/trのようなコマンドでこれらをどうやってエミュレートできますか?

292
Koran Molovik

DOSからUnixへの変換にはtrを使用できます。ただし、CRがCRLFバイトペアの最初のバイトとしてファイルに存在する場合にのみ、これを安全に実行できます。これは通常そうです。あなたはそれから使う:

tr -d '\015' <DOS-file >UNIX-file

DOS-fileという名前はUNIX-fileという名前とは異なることに注意してください。同じ名前を2回使用しようとすると、ファイルにデータがなくなります。

あなたはそれを逆にすることはできません(標準の 'tr'で)。

あなたがスクリプトにキャリッジリターンを入力する方法を知っていれば(control-V、 control-M 次にcontrol-M)を入力します。

sed 's/^M$//'     # DOS to Unix
sed 's/$/^M/'     # Unix to DOS

ここで、 '^ M'はcontrol-M文字です。キャリッジリターンを指定するためにbashANSI-C引用 メカニズムを使用することもできます。

sed $'s/\r$//'     # DOS to Unix
sed $'s/$/\r/'     # Unix to DOS

ただし、これを非常に頻繁に(大まかに言って)実行する必要がある場合は、変換プログラムをインストールするほうがはるかに賢明です(例: dos2unix および unix2dos 、または dtou および utod )を使用してください。

299
tr -d "\r" < file

sedを使った例は ここ を見てください。

# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format.
sed 's/.$//'               # assumes that all lines end with CR/LF
sed 's/^M$//'              # in bash/tcsh, press Ctrl-V then Ctrl-M
sed 's/\x0D$//'            # works on ssed, gsed 3.02.80 or higher

# IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format.
sed "s/$/`echo -e \\\r`/"            # command line under ksh
sed 's/$'"/`echo \\\r`/"             # command line under bash
sed "s/$/`echo \\\r`/"               # command line under zsh
sed 's/$/\r/'                        # gsed 3.02.80 or higher

インプレース変換には sed -i を使用します。 sed -i 's/..../' file

56
ghostdog74

POSIXでこれを行うのは難しいです。

  • POSIX Sed\rまたは\15をサポートしません。そうであっても、インプレースオプション-iはPOSIXではありません

  • POSIX Awk\r\15をサポートしますが、-i inplaceオプションはPOSIXではありません

  • d2udos2unixPOSIXユーティリティではありません しかしex

  • POSIX ex\r\15\nまたは\12をサポートしません

復帰改行を削除するには。

ex -bsc '%!awk "{sub(/\r/,\"\")}1"' -cx file

改行を追加するには:

ex -bsc '%!awk "{sub(/$/,\"\r\")}1"' -cx file
36
Steven Penny

AWKを使うと、次のことができます。

awk '{ sub("\r$", ""); print }' dos.txt > unix.txt

Perlを使えば、次のことができます。

Perl -pe 's/\r$//' < dos.txt > unix.txt
20
codaddict

この問題は標準的なツールで解決できますが、20年以上前にflipの作者であるRahul Dhesiによって書かれた Zoo コマンドをインストールすることをお勧めするという不信心のための十分なトラップがたくさんあります。たとえば、バイナリファイルの不注意による破壊を避けながら、ファイル形式を変換するのに優れた仕事をします。

19
Norman Ramsey

これまでに投稿された解決策は、DOS/WindowsのCRLFをUnixのLFに変換するという問題の一部だけを扱っています。欠けている部分は、DOSがCRLFを行 セパレータ として使用するのに対し、UnixはLFを行 ターミネータ として使用することです。違いは、DOSファイルは(通常)ファイルの最後の行の後には何も持っていないのに対し、Unixはそうではないということです。適切に変換するためには、最後のLFを追加する必要があります(ファイルの長さが0、つまり行がまったくない場合を除く)。私のお気に入りの呪文は(MacスタイルのCRで区切られたファイルを扱うためのロジックが少し追加されていて、すでにunixフォーマットになっているものではありません)、少しPerlです。

Perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt

これはUnix化されたバージョンのファイルをstdoutに送ることに注意してください。ファイルをUnix化されたバージョンに置き換えたい場合は、Perlの-iフラグを追加してください。

14
Gordon Davisson

dos2unix にアクセスできないがこのページを読むことができる場合は、ここから/ paste dos2unix.py をコピーできます。

#!/usr/bin/env python
"""\
convert dos linefeeds (crlf) to unix (lf)
usage: dos2unix.py <input> <output>
"""
import sys

if len(sys.argv[1:]) != 2:
  sys.exit(__doc__)

content = ''
outsize = 0
with open(sys.argv[1], 'rb') as infile:
  content = infile.read()
with open(sys.argv[2], 'wb') as output:
  for line in content.splitlines():
    outsize += len(line) + 1
    output.write(line + '\n')

print("Done. Saved %s bytes." % (len(content)-outsize))

スーパーユーザー からクロスポストされました。

13

-c {command}オプションを付けてプログラム的にvimを使うことができます。

UnixへのDo:

vim file.txt -c "set ff=unix" -c ":wq"

Unixからdosへ:

vim file.txt -c "set ff=dos" -c ":wq"

"set ff = unix/dos"はファイルのファイルフォーマット(ff)をUnix/DOSの行末フォーマットに変更することを意味します。

":wq"はファイルをディスクに書き込み、エディタを終了することを意味します(ループ内でコマンドを使用できるようにします)。

9
Johan Zicola

PCREで簡単に超デュパー。

スクリプトとして、または$@をファイルに置き換えます。

#!/usr/bin/env bash
Perl -pi -e 's/\r\n/\n/g' -- $@

これでファイルが上書きされます。

私はこれをバックアップ(バージョン管理など)でのみ行うことをお勧めします。

8
ThorSummoner

その場でファイルを変換するには

dos2unix <filename>

変換したテキストを別のファイルに出力するには

dos2unix -n <input-file> <output-file>

それはすでにUbuntuにインストールされていて、brew install dos2unixで自作で利用可能です。


私はこのユーティリティに代わるものを明示的に要求する質問を知っていますが、これは "dosをunixの行末に変換する"の最初のGoogle検索結果です。

8
Boris

プログラムを使わないでもっと簡単なawkの解決策:

awk -v ORS='\r\n' '1' unix.txt > dos.txt

技術的には '1'があなたのプログラムです。b/ c awkは与えられたオプションを必要とします。

_ update _ :このページを久しぶりに再訪したところ、まだ誰も内部ソリューションを投稿していないことに気付いたので、ここに1つあります。

while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done < dos.txt > unix.txt
6
nawK

おもしろいことに、私のウィンドウズのgit-bashでは、sed ""がすでにうまくいっています。

$ echo -e "abc\r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text

私の推測では、sedは入力から行を読み込むときにそれらを無視し、常に出力にunix行の末尾を書き込みます。

4
user829755

これは私のために働きました

tr "\r" "\n" < sampledata.csv > sampledata2.csv 
3
Santosh

同じ質問を熟考する必要がありました(Windows側ですが、Linuxにも同様に適用できます)。驚くほど、古き良きZip -llオプション( Info-Zip):

Zip -ll textfiles-lf.Zip files-with-crlf-eol.*
unzip textfiles-lf.Zip 

注:これにより、元のファイル名を保持したまま、行末をLFに変換するZipファイルが作成されます。次に、unzipはファイルをZip形式で抽出します。つまり、元の名前(ただしLFの末尾)を使用して、ローカルの元のファイルを上書きするように促します。

Zip --helpからの関連する抜粋:

Zip --help
...
-l   convert LF to CR LF (-ll CR LF to LF)
3
vmsnomad

TIMTOWTDI!

Perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof' PCfile.txt

@GordonDavissonに基づく

[noeol]の可能性を考慮する必要があります...

2
lzc

あなたはawkを使うことができます。レコード区切り文字(RS)を、すべての可能な改行文字(複数可)に一致する正規表現に設定します。そして、出力レコード区切り文字(ORS)をunixスタイルの改行文字に設定します。

awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt
1
kazmer

Mac osxの場合、自作がインストールされていれば[ http://brew.sh/][1]

brew install dos2unix

for csv in *.csv; do dos2unix -c mac ${csv}; done;

このコマンドでファイルが適切に変更されるため、ファイルのコピーを作成したことを確認してください。 -c macオプションを指定すると、スイッチはosxと互換性があります。

1
Ashley Raiteri

Linuxでは、sedで^ M(ctrl-M)を* nix改行(^ J)に変換するのは簡単です。

CLIではこのようなことになりますが、実際にはテキストに改行が入ります。しかし、\はその^ Jをsedに渡します。

sed 's/^M/\
/g' < ffmpeg.log > new.log

入力するときに^ V(ctrl-V)、^ M(ctrl-M)、および\(バックスラッシュ)を使用してこれを取得します。

sed 's/^V^M/\^V^J/g' < ffmpeg.log > new.log
1
jet

Jonathan LefflerのUnixからDOSへのソリューションの拡張として、ファイルの現在の行末がわからないときに安全にDOSに変換することができます。

sed '/^M$/! s/$/^M/'

これは、CRLFに変換する前に、その行がまだCRLFで終わっていないことを確認します。

0
Gannet

最終的に追加のファイルを必要とせずに直接変換し、後で削除して名前を変更することができるように、私は受け入れられた答えに基づいてスクリプトを作成しました。

convert-crlf-to-lf() {
    file="$1"
    tr -d '\015' <"$file" >"$file"2
    rm -rf "$file"
    mv "$file"2 "$file"
}

あなたが "file1.txt2"が既に存在していないか、それが上書きされるであろうことを "file1.txt"のようなファイルがあるかどうか確かめてください、私はファイルを保存するための一時的な場所としてこれを使います。

0
OZZIE
sed --expression='s/\r\n/\n/g'

質問がsedに言及しているので、これはこれを達成するためにsedを使用する最も直接的な方法です。式が言うことは、すべてのキャリッジリターンとラインフィードを単にラインフィードのみに置き換えます。それはあなたがWindowsからUnixに行くときあなたが必要とするものです。私はそれが機能することを確認しました。

0
John Paul