現在のパスではなくフルパスを使用するたびに「名前の変更」が異なる動作をするのはなぜですか?

現在のパスではなくフルパスを使用するたびに「名前の変更」が異なる動作をするのはなぜですか?

わかりました。質問に答えるOPにはUbuntuに複数のリポジトリがあり、関連していないソフトウェアをインストールすると問題が発生する可能性があります。単一のライナーを使用してPPAを無効にしてから、一連の指示に従うことrenameをお勧めします。すべて大丈夫です。質問に答えは残します...いいえ。結果はrename私が期待していたものとは異なりました。

sudo rename s/list/list\.disable/g /etc/apt/sources.list.d/*.list

/etc/apt/sources.list.d/これにより、renameはで終わるすべてのファイルを見て.listから.list置き換えることを期待します.list.disable。ほぼ同じコマンドで別の回答を得ましたが、OPはフィードバックを提供せず、最初にテストしていない状況にあります。この理論は次に廃棄された。驚いたことに、OPは次の行で問題を発見しました。

Can't rename /etc/apt/sources.list.d/iaz-battery-status-quantal.list /etc/apt/sources.list.disable.d/iaz-battery-status-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/ubuntu-wine-ppa-quantal.list /etc/apt/sources.list.disable.d/ubuntu-wine-ppa-quantal.list.disable: No such file or directory
Can't rename /etc/apt/sources.list.d/webupd8team-java-raring.list /etc/apt/sources.list.disable.d/webupd8team-java-raring.list.disable: No such file or directory

奇妙な感じがしてこの理論を直接テストしてみましたが、同じ結果が出ました。次に、問題が発生するたびに、通常は正規表現ではなく正規表現を使用します。?私は多くの歪んだ方法で正規表現を変更しました。

  • s/.list/.list.disable/g
  • s/.list/.list.disable/g
  • /リスト/list.disable/
  • 他の組み合わせは覚えていません。

まあ、私は正規表現が問題だとは思わなかったので、セレクタを見て、それを変更して正規表現/etc/apt/sources.list.d/*テストをリサイクルしました。喜びはありません。少し苦労してtouch some.listコマンドを適用しました。

rename s/\.list/\.list\.disable/g *

ビンゴ!今は全身がコントロールされるような感じがします。私は答えを修正し、私の人生を続けました...いいえ!これは許容できません。なぜ?マニュアルを確認しましたが、驚くべきことに、現在のパス例のみを使用しています。これは普通ですか?それとも、機能が実装されていないので、そうですか?それとも私の理論を信じないように始めるべきですか?

答え1

この-nパラメータを使用してテスト実行モードで実行しますrename。これはモードをテストするのに役立ちます。

martin@martin ~ % rename -n s/list/list.disable/g /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
 => /etc/apt/sources.list.disable.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
 => /etc/apt/sources.list.disable.d/steam.list.disable
[...]

ここで明らかなエラーはパターンlist一致なので、フォルダとフォルダに含まれるファイルの名前を変更しようとしています。sources.list.d

代わりにこのモードを使用してください。

rename -n 's/\.list$/.list.disable/' /etc/apt/sources.list.d/*.list | sed 's/renamed as/\n =>/g'
[...]
/etc/apt/sources.list.d/spotify.list 
 => /etc/apt/sources.list.d/spotify.list.disable
/etc/apt/sources.list.d/steam.list 
 => /etc/apt/sources.list.d/steam.list.disable
[...]

違いは次のとおりです。

  1. .検索パターンで引用符を使用すると、\.点は文字ではなく実際の点とのみ一致します(正規表現で引用符がない点が通常行うこと)。

  2. 次の$リストは「文字列の終わり」を示しています。これはファイル名の末尾にある「.list」のみが一致して置き換えられていることを確認し、パスまたはファイル名の他の部分の「.list」はそうではありません。

  3. 代替文字列からドットを引用する必要はありません。したがって、「.list.disable」は.もはや特別な意味を持たないため、バックスラッシュなしで動作します。

  4. また、シェルが何らかの方法で正規表現を変更するのを防ぐために、正規表現を一重引用符で囲みました。

答え2

問題はg、実際にモードを固定する必要があるときにグローバルスイッチを使用していることです。あなたが書いたように:

s/a/b/g

文字列のすべての位置で a を b に置き換えます。これにより、存在しないディレクトリのパス名を変更しようとします。これはディレクトリでタスクを実行すると問題がなくなる理由でもあり、置き換える一致が1つしかありません。

パターンを固定したいと思います。

s/\.list$/.list.disable/

これにより、存在しないディレクトリ/etc/apt/sources.list.disable.d/にファイルを移動しようとするのを防ぎます(したがって、そのディレクトリにファイルを移動することはできません)。

関連情報