sed 置換と削除コマンドで NUL 文字を区切り文字として使用するには?

sed 置換と削除コマンドで NUL 文字を区切り文字として使用するには?

これは、区切り記号/区切り記号/path/to/aとして/path/to/b使用して交換しようとしたときに試みたものです。NUL

$ cat pathsList| sed -r -e 's\0/path/to/a\0/path/to/b\0g'
sed: -e expression #1, char 27: number option to `s' command may not be zero

私が行きたい場所NUL NULおよび/許可されていない唯一の文字でext4fsあり、/パス名の区切り文字として広く使用されています。また、データを使用するためにデータを参照または逆参照することも避けたいと思いますsed

NUL区切り文字として使用できない場合は、データを引用して分離するよりも優れた解決策があります。

$ sed --version
sed (GNU sed) 4.4

ベストアンサー1

残念ながら、s///sedでコマンドの区切り文字としてNULを使用することは不可能に見えます。

NUL文字を含む文字列を生成したい場合は、$'...'bashや他のシェル認識形式を使用できるので、次のように機能すると思います。

sed -r -e $'s\0o\0x\0g'

ただし、Linux(および通常はUnix)で引数が渡される方法のため、NULを含む文字列を渡すことは実際には不可能です。なぜなら得ることができるのはargc(引数の数)とargv(配列)だけで、char *その後NUL-だからです。終了文字列(C文字列)は、パラメータを取得する唯一の方法です。つまり、すべてのsed(またはすべてのプログラム)は、渡されたコンテンツが$'s\0o\0x\0g'単純であることを"s"確認します(そして、NULの場合はそれを文字列の末尾として扱う必要があります)。

外部ファイルとしてsedに渡すとうまくいくと思いました。この場合、sedはNULを含むことがわかり、文字列全体を長さごとに追跡できるため、次のことを試しました。

$ cat -v script.sed 
s^@o^@x^@g

s^@は NUL バイトです。Ctrlv000ASCII値を介して文字を入力するためのvimキー入力(3つの0)を使用してvimに挿入しました。

しかし、これもうまくいかないようです。

$ echo "/path/to/a/folder" | sed -r -f script.sed 
sed: file script.sed line 1: delimiter character is not a single-byte character

s興味深いことに、これはスクリプトファイルに1つしかない場合とは異なります。この場合、sedは文句を言うunterminated 's' command...だから文字列の長さを追跡しているように見えますが、それでもNULを区切り文字として使用することについて不満があるようです。 。

ソースコードを見ると、sedこれが意図的なものかバグなのかはわかりません。is_mb_char()バイトがマルチバイト文字の一部であるかどうかを検出する関数でのNUL処理このように:

case 0: /* Special case of mbrtowc(3): the NUL character */
  /* TODO: test this */
  return 1;

この場合、return 1「はい、マルチバイト文字です」を意味しますが、そうではありません。

上記の数行のコメントは次のとおりです。:

/*
 * Return zero in all other cases:
 *   CH is a valid single-byte character (e.g. 0x01-0x7F in UTF-8 locales);
 *   CH is an invalid byte in a multibyte sequence for the currentl locale,
 *   CH is the NUL byte.
 */

それではreturn 0意図的なものではないだろうか?

これ犯罪このコードが導入されたコンテキストにはもはやコンテキストがありません。

これマニュアルページmbrtowc(3)L'\0'私はそれが一種のマルチバイトNULだと思ったと言っていましたが、それで彼らはこのように扱うことにしましたか?

この情報がまだ役に立つことを願っています!

おすすめ記事