回答:
あなたの方法は、区切り記号($IFS
)が読み取りを分割するために使用しているスペースに書き込むすべてのものに改行を追加することです。それを改行に分割するのではなく、全部を取り出して渡すだけです。上記のコード全体をこれに減らすことができます:
cat - > $file
切り捨てビットは必要ありません。これにより、STDINストリーム全体が切り捨てられて書き込まれます。
編集: zshを使用> $file
している場合は、猫の代わりに使用できます。ファイルにリダイレクトして切り詰めていますが、何かがSTDINを受け入れるのを待っている場合は、その時点で読み込まれます。bashを使用してこのようなことができると思いますが、特別なモードを設定する必要があります。
> $file
。これは、親シェルスクリプトで標準入力を最初に探す場合にのみ機能します。基本的に、Davidのコードはすべて1文字に減らすことができますがcat -
、一見して理解できるので、よりエレガントでトラブルが少ないと思います。
cat
だけ困らせるのUUOCの狂信秒一緒に、
cat
それを使用することを主張する人々がコードを読むために必ず精神的な体操をしなければならないからです。名前付きパイプも良いターゲットです。
テキストファイルを文字通り読み取るには、次のread
2つの方法で出力を処理するplainを使用しないでください。
read
\
エスケープ文字として解釈します。read -r
これをオフにするために使用します。read
$IFS
;の文字で単語に分割されます。IFS
これをオフにするには、空の文字列に設定します。テキストファイルを1行ずつ処理する通常のイディオムは
while IFS= read -r line; do …
このイディオムの説明については、「ではなく、なぜwhile IFS= read
頻繁に使用されるのかIFS=; while read..
」を参照してください。。
文字列を文字通りに書くには、文字echo
列を2つの方法で処理するplainを使用しないでください。
echo
バックスラッシュエスケープを処理します。(bashでは、xpg_echo
オプションが設定されているます。)-n
または-e
(正確なセットはシェルによって異なります)。文字列を文字通り印刷するポータブルな方法は、printf
です。(bashには、入力がのオプションのように見えないことがわかっている場合を除き、より良い方法はありませんecho
。)最初のフォームを使用して正確な文字列を印刷し、改行を追加する場合は2番目のフォームを使用します。
printf %s "$line"
printf '%s\n' "$line"
シェルでバイナリデータを処理することはできませんが、ほとんどの大学の最新バージョンのユーティリティは任意のデータに対処できます。すべての入力を出力に渡すには、を使用しますcat
。接線に沿って進むことecho -n ''
は、何もしない複雑で移植性のない方法です。echo -n
(シェルに依存しない)同じくらい良いでしょうし、:
よりシンプルで完全に移植可能です。
: >| "$file"
cat >>"$file"
または、より単純な、
cat >|"$file"
スクリプトでは、デフォルトではオフになっているため>|
、通常は使用する必要はありませんnoclobber
。
これはまさにあなたが望むことをします:
( while read -r -d '' ; do
printf %s'\0' "${REPLY}" ;
done ;
# When read hits EOF, it returns non-zero which exits the while loop.
# That data still needs to be output:
printf %s "${REPLY}"
) >> ${file}
ただし、メモリ使用量に注意してください。これは、ヌル区切り形式で入力を読み取ります。
入力に\0
nullバイトがない場合、bashは最初に入力の内容全体をメモリに読み込んでから出力する必要があります。
切り捨て手順について:
echo -n '' >| "$file" #Truncate the file
より単純で同等なものは次のとおりです。
> ${file} #Truncate the file