シェルでNULL文字を処理する移植可能な方法はありますか?
一般的な例は、シェル(およびシェルのみ)の出力をfind ... -print0
パイプまたはコマンド置換の結果に分割することです。たとえば、ポータブルとは理想的には、シェルが強力でない、または詰まらないことを意味しbash
ますzsh
。 「ネイキッドPOSIXシェル」(すべてのPOSIXバージョン)でこれは可能ですか?
答え1
null
POSIXは、テキストを含む文字を処理するための標準ユーティリティを考慮していません。-print0
使用するオプション自体find
はのGNU
影響を受けませんPOSIX
。
null
sを含むデータストリームを処理するためにシェルスクリプトを使用する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」行を無視してください。また、ファイルに同じテキストがある場合は、リストから手動で消去する必要があるいくつかの無実のファイルが表示されることがあります。
ヌル文字が改行文字の位置にない場合は、単に削除してください。
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
ヌル文字を含むファイルを消去するには(すべて改行位置にあると仮定)、次のコマンドを使用します。
tr -s '\000' '\n' < inputfile > outputfile
tr
一度に複数のファイルを処理する方法をあまり調査せずに。