Linuxでバックスラッシュのある項目を見つけて名前を変更すると、期待どおりに機能しません。

Linuxでバックスラッシュのある項目を見つけて名前を変更すると、期待どおりに機能しません。

バックスラッシュを含むディレクトリでいくつかのファイルを見つけて名前を変更するためにいくつかの方法を試しました。 Webアプリケーションによって生成されたこれらのファイルには引用符はありません。検索して置き換えようとしましたが、上位レベルでは失敗したようです。既定では、親フォルダの名前を変更しますが、削除すると以前の親名を参照するため、サブフォルダにドロップダウンできないのと同じです。

フォルダ構造:

'ano\ther' -> 'chi\ld'

私が実行したとき:

for file in `find . -name '*\\\*'`; do mv -v "$file" "${file/\\/}"; done`

または

find . -exec rename 's/\\//g' {} +

または

find . -name "*\\\*" -exec rename 's/\\//g' {} +

ほぼすべて同じエラーが発生しますが、親ディレクトリまたは現在のディレクトリの名前を変更すると、降順で失敗します。

Can't rename ./ano\ter/yo\yo ./anoter/yoyo: No such file or directory

私のコマンドから何が欠けていますか?

答え1

以下を行う必要があります。

  • そのようにfind出力を繰り返さないでください。
  • `...`廃止予定のコマンド置換形式を避けてください。
  • 葉のある枝の前に葉の名前を変更します。
  • \フルパスではなくファイル名のsだけを削除してください。
  • リテラルバックスラッシュが必要な場合は二重引用符を使用しないでください。

だから:

find . -depth -name '*\\*' -exec rename -d 's/\\//g' {} +

(これはperlベースのバリエーションを想定しており、renameこの-dオプションを受け入れるとデフォルト名のみが変更されます。)

または:

find . -depth -name '*\\*' -exec zsh -c '
  for file do
    mv -v -- $file $file:h/${file:t:gs/\\/}
  done' zsh {} +

またはzshでは、次のようにします。

autoload zmv
zmv -v '(**/)(*\\*)(#qD)' '$1$2:gs/\\/'

$var:s/string/replacement/ここではcshスタイル(繰り返しを含む)を使用しますが、g必要に応じてkshスタイル${var//pattern/replacement}//繰り返しを含む)を使用することもできます。

zmv(#qD)デフォルトは、隠されたファイルも考慮して、通常は目的の深さ優先ナビゲーションを実行することです。 aとファイルのzmv両方が存在するなど、特定の問題が検出された場合は、両方に名前が変更されます。a\bca\b\cabc

答え2

両方の「es」を同時に削除しようとすると、「./anoter」ディレクトリが存在しないため、エラーメッセージが表示されると推測されます。

find.txtファイルに追加するだけで、-type fディレクトリ構造内のすべてのファイルを処理できます。ただし、サブディレクトリレベルが1つだけであることがわかっている場合(または名前に「esのみ」がある少なくとも1つのレベル)、まだディレクトリがあり、findを使用してそのディレクトリを見つけることができます-type dano\ther/d\ir/同じエラーが原因で失敗します。

-execdironの代わりにusing -exec(およびusing)に関連するものを取得することもできますが、-depth私は試したことがないので、-execdirマンページで提案をすばやく読みました。考えてみると、これを行うと、ファイルを最初に処理する必要があるかもしれません。

関連情報