web-dev-qa-db-ja.com

Cat、Grep、リダイレクト出力...空のファイル?

私は走った

cat /opt/webapplications/Word/readme.log | grep -v 'Apple'

そして、私は期待していたcliの出力を取得しました。これはreadme.logのすべての行で、 'Apple'が含まれていませんでした...

次に走った...

cat /opt/webapplications/Word/readme.log | grep -v 'Apple' > /opt/webapplications/Word/readme.log

ただし、/opt/webapplications/Word/readme.logは空白です。

なぜこれが起こったのか、または私がこれについて行ったはずの正しい方法を誰かに説明できますか?

8

これは最初に>は、書き込み先のファイルを作成することです。ファイルがすでに存在する場合、その内容は削除されます。 (また、catはSTDINだけでなくファイルでも機能するため、ステートメントでgrepを使用する必要はまったくありません。)

これを行う正しい方法は、一時ファイルを使用して読み取りまたは書き込みを行うことです。だからどちらか

cp /opt/webapplications/Word/readme.log /tmp/readme.log
grep -v 'Apple' /tmp/readme.log > /opt/webapplications/Word/readme.log

または

grep -v 'Apple' /opt/webapplications/Word/readme.log > /tmp/readme.log
mv /tmp/readme.log /opt/webapplications/Word/readme.log

うまくいくでしょう。

14
Jenny D

同じファイルにリダイレクトする場合(>)、シェルはcatコマンドが呼び出されて入力が読み取られる前にファイルを作成/切り捨てる場合があります(参照: 「file1> file1」を機能しないのはなぜですか? ) 。ファイルをフィルタリングする場合は、出力を別のファイルにリダイレクトするか、リダイレクトを回避することをお勧めします。次に例を示します。

grep -v 'Apple' readme.log | tee readme.log

より適切で安全な方法は、そのような操作用に設計されたインプレースエディターを使用することです。

sed -i '.bak' '/Apple/d' readme.log

またはex(Vimの一部)を使用:

ex +g/Apple/d -cwq readme.log

関連:

1
kenorb