sedがハードリンクを破壊するのを防ぐ方法は?

sedがハードリンクを破壊するのを防ぐ方法は?

私の問題は次のようになりますsed -iがシンボリックリンクを破るのを防ぐ方法は?しかし、ハードリンクが含まれています。

sedを使用してファイルを処理すると、sed -iファイル内のすべてのハードリンクが削除されます。 sedは一時ファイルに書き込んでから移動する方法で動作するためです。この--follow-symlinksパラメータはハードリンクでは役に立ちません。

やや醜いアプローチを使用する以外に他のオプションはありますか?

sed 's/cat/dog/' pet_link > pet_link

答え1

sed 's/cat/dog/'Bourneに似たシェルを使用してファイルサイズを変更しない代替の場合は、次のことができます。

sed 's/cat/dog/' < file 1<> file

35歳以上ほとんど知られていない人基準 <>オペレータは読み取り+書き込みモードでファイルを開きます。切り捨てなし。デフォルトでは、これはsed出力を入力に書き込みます。出力がsedまだ読み取っていないファイル部分を上書きしないようにすることが重要です。

ファイルサイズを小さくする交換の場合は、次のようにしますksh93

sed 's/hippopotamus/ant/' < file 1<>; file

<>;、リダイレクトされたコマンドが成功すると、コマンドが完了した時点でファイルが切り捨てられることを除いて、ksh93同じ拡張子です。<>

またはパールを使用してください:

perl -pe 's/hippopotamus/ant/;
          END{truncate STDOUT, tell STDOUT}' < file 1<> file

それ以外の場合は、標準形式を使用してください。

cp -i file file.back &&
  sed 's/dog/horse/g' < file.back > file # && rm -f file.back

1 BourneシェルとKornシェルの初期バージョンでは、元の実装が実際に破損していましたが、これは1980年代後半に修正されました。 Almquistシェルは最初はそれをサポートしません。

答え2

sedこれはSトレメ緊急室それではない文書エディターなので、人々はファイルを編集しようとするので、それを乱用する傾向があります。デフォルトでは、-iこのオプションは非標準のFreeBSD拡張であり(他のオペレーティングシステムでは利用できません)、2番目にファイルを編集しません。コピーを作成し、元のファイルをコピーに置き換えます。バッシュFAQ

別の方法はedまたはex同様の構文(Vimの一部)を持つコマンドです。

ex +%s/cat/dog/e -scwq pet_link

またはフォローしてください@ワイルドカードおすすめ:

printf '%s\n' '%s/cat/dog/' x | ex pet_link

複数のファイルの場合は、次のものを使用できます。

ex "+bufdo! %s/foo/bar/ge" -scxa **/*.lnk

シェルがサポートしている場合新しいワイルドカードオプション(pass:有効shopt -s globstar)、**この場合、usingは再帰的に機能します。


詳細POSIX試してみる構文(したがって@ワイルドカード提案):

for f in *.txt; do printf '%s\n' '%s/cat/dog/g' x | ex "$f"; done

または:

find . -type f -exec sh -c 'for f; do printf "%s\n" "%s/cat/dog/g" x | ex "$f"; done' sh {} +

関連:

答え3

少しed

$ ed pet_link <<END_OF_ED
g/cat/s//dog/
w
END_OF_ED

ハードリンクは壊れません。

答え4

私はこれがうまくいくことを知っていました(シンボリックリンクとハードリンクを維持)。

sed 's/cat/dog/' pet_link > pet_link.tmp
cat pet_link.tmp > pet_link
rm pet_link.tmp

関連情報