1

\r\n特に、すべてをに変換しようとしてい\r\r\nます。これは、iCloud の IMAP サーバー\r\r\nがプロトコルとすべての感性を壊して送信するためです (私の唯一の実用的な理論は、彼らがこれを行ったので、数年前にリリースされた独自の IMAP クライアントでのみ動作するということです)、これをシミュレートするための単体テストを作成する必要があります。

これを標準の UNIX ツールで機能させるのは、行末の処理方法が原因で非常に困難です。

sed 's/\r\n/\r\r\n/g'- いいえ、何もしません

sed 's/\r/\r\r/g'- また、何もしません

tr文字列を扱うのにはあまり役に立ちません。単一の文字でのみ動作し、文字数を保持しているようです。

Unix ツールを使用してこの低レベルのことを行う方法が実際にはわかりません。最悪の場合、C の数行でこれを行うことができますが、これをより標準的に行う方法を学びたいと思います。

Jim の回答での議論によると、Mac OS X (BSD) 上の sed のバージョンは、Linux とは動作が異なるようです。理想的には、Mac ソリューションが必要ですが、別のマシンで多かれ少なかれこれを行うことができます。

4

4 に答える 4

3

bashをシェルとして使用している場合は、そのANSI C クォーティング機能を使用して、Mac OS Xsedを必要に応じて動作させることができます。

sed -e $'s/$/\r\r/'

ANSI Cの$'...'引用符付き文字列です。内部の文字の大部分 (だけ) は変更されません。2 つの\rシーケンスは、文字列内のキャリッジ リターンに置き換えられます。

例えば:

$ sed -e $'s/$/\r\r/' genouterr.sh | odx
0x0000: 23 21 2F 62 69 6E 2F 62 61 73 68 0D 0D 0A 66 6F   #!/bin/bash...fo
0x0010: 72 20 69 20 69 6E 20 7B 30 31 2E 2E 35 30 7D 0D   r i in {01..50}.
0x0020: 0D 0A 64 6F 0D 0D 0A 20 20 65 63 68 6F 20 22 73   ..do...  echo "s
0x0030: 74 64 6F 75 74 20 24 69 22 0D 0D 0A 20 20 65 63   tdout $i"...  ec
0x0040: 68 6F 20 22 73 74 64 65 72 72 20 24 69 22 20 3E   ho "stderr $i" >
0x0050: 26 32 0D 0D 0A 64 6F 6E 65 0D 0D 0A               &2...done...
0x005C:
$

16進ダンプ(odx自作プログラムですが、私はその形式が好きです)は\r、元にはなかった各改行(0A)の前に2(0D)バイトがあることを示しています。sed明らかに、16 進ダンプ プログラムの選択は、コマンドの有効性と ANSI C クォーティング メカニズムには影響しません。

CRLF を CRCRLF に変更する必要がある場合は、次を使用します。

sed -e $'s/\r$/\r\r/'

キャリッジ リターンを削除したいが、行末だけを削除したい場合は、次を使用できます。

sed -e $'s/\r\r*$//'

(tr改行の前にあるものだけでなく、すべての改行を削除するために使用できます。)

于 2013-08-20T20:35:59.480 に答える
2

MacOSX の 'sed' は、Linux とは少し異なる動作をします。このソースからの手順を試してみてください。

sed -e 's/ /\'$'\n/g'

新しい行を追加します。

「gsed」を使用する別のオプションがあります。これは、sed の最新バージョンです (Linux に匹敵します)。おそらくLinuxソリューションを使用できます: sed 's/\r\n/\r\r\n/g'

于 2013-08-20T20:28:18.317 に答える
1

行末アンカー文字「$」を使用して、目的を達成できます。

% od -c foo
0000000   l   i   n   e   1  \r  \n   l   i   n   e   2  \r  \n   l   i
0000020   n   e   3  \r  \n
0000025
% sed 's/\r$/\r\r/g' < foo > bar
% od -c bar
0000000   l   i   n   e   1  \r  \r  \n   l   i   n   e   2  \r  \r  \n
0000020   l   i   n   e   3  \r  \r  \n
0000030

上記は GNU sed では機能しますが、BSD sed では機能しません (置換文字列で期待されるように \r を処理しません)。Mac またはその他の BSD 風の sed バリアントでは、バックスラッシュでエスケープされたリテラル(空白) ASCII 戻り文字を指定することで、目的の置換を実現できるはずです。

詳細については、この質問を参照してください。

于 2013-08-20T20:01:58.863 に答える