シェルでのNULL文字の処理

シェルでのNULL文字の処理

シェルでNULL文字を処理する移植可能な方法はありますか?

一般的な例は、シェル(およびシェルのみ)の出力をfind ... -print0パイプまたはコマンド置換の結果に分割することです。たとえば、ポータブルとは理想的には、シェルが強力でない、または詰まらないことを意味しbashますzsh。 「ネイキッドPOSIXシェル」(すべてのPOSIXバージョン)でこれは可能ですか?

答え1

nullPOSIXは、テキストを含む文字を処理するための標準ユーティリティを考慮していません。-print0使用するオプション自体findはのGNU影響を受けませんPOSIX

nullsを含むデータストリームを処理するためにシェルスクリプトを使用する1つの方法POSIXは、まずそれを実際のテキストに変換odしてそのテキストを処理することです。

とにかく、もしあれば、そもそもそのような制限がないGNU find他のユーティリティがあるでしょう。GNU

答え2

Bashはread'のオプションを使用して-dこれを処理できます。

find . -print0 | while read -r -d '' line; do
    # something with $line
done

しかし、これがPOSIXかどうかはわかりません。

答え3

後ろに同様の質問を探す、これは私がしばらくして見つけたものです...これがPOSIXシェルで可能かどうかはわかりません。 Cygwinでこれを試しました。ちょうど楽しみのためにnull文字を使用して問題を解決しました。

問題が次のようになると想像してください。ヌル文字を含む(一部)ファイルがあります。これらのファイルが何であるか、どこにあるのか正確にはわかりません。あなたの使命は、すべての可能なファイルからヌル文字を削除することです。

以下の最初のコマンドはNULL文字を含む行を表示し、他のコマンドはNULL文字を改行に変換します(最後のコマンドは一時ファイルを削除します)。

find . ! -type d -exec perl -ne '/\000/ and print;' {} \; > /tmp/null-lines
tr -s '\000' '\n' < /tmp/null-lines > with-null-lines.txt
rm /tmp/null-lines

次に、結果行の各行を読み、その行がどのファイルに属しているかを調べる必要があります。これを行うには、まず確認する必要があるすべてのファイルを保存し、一致する行があることを確認します。

find . ! -type d -print > files.txt
while read line; do while read line2; do if grep -q "$line2" "$line"; then echo "$line" >> examination.txt; fi; done < with-null-lines.txt; done < files.txt

(ループを再実行する前に「examination.txt」ファイルを削除してください)

これで、発生回数を数えて発生回数が1を超えると、null文字が複数である可能性が高くなります(もちろん、1つしかないと検索が難しくなります)。

uniq -c examination.txt | grep -v "1"

これには、ヌル文字を含む(ほとんどの)ファイルをリストする必要があります。 「with-null-lines.txt」行を無視してください。また、ファイルに同じテキストがある場合は、リストから手動で消去する必要があるいくつかの無実のファイルが表示されることがあります。

  1. ヌル文字が改行文字の位置にない場合は、単に削除してください。

    uniq -d examination.txt > files-to-clean.txt
    while read line; do ex -s +"%s/\%x00//g" -cwq $line; done < files-to-clean.txt
    

    またはtrファイルの場合は、を使用してください。

    tr -d '\000' < inputfile > outputfile
    
  2. ヌル文字を含むファイルを消去するには(すべて改行位置にあると仮定)、次のコマンドを使用します。

    tr -s '\000' '\n' < inputfile > outputfile
    

    tr一度に複数のファイルを処理する方法をあまり調査せずに。

関連情報