一部の隠しファイルのみを削除する方法は?

一部の隠しファイルのみを削除する方法は?

ツリー全体を通過し、一部(例:「.@__thumb」)を除くすべての隠しファイル(「.git」など)を削除するスクリプトを作成したいと思います。私は私のツリーを通過し、「.」で始まるすべてのファイルを削除するスクリプトを作成しました。

ここにいる:

find . -depth -type d -name '.*' |
while read f
   do
                dn=`dirname "$f"`
                bn=`basename "$f"`
                mv "$dn/$bn" "$dn/${bn//.}"
done

その後、フォルダ/ファイル名が「.@__thumb」(削除したくないフォルダ)の場合は、「.@__thumb」が削除されないように調整して条件を追加したいと思います。

わかります:

thumb=".@__thumb"
echo $thumb
 
find . -depth -type d -name '.*' |
while read f
   do
        if [[ $bn != $thumb ]]
        then
                dn=`dirname "$f"`
                bn=`basename "$f"`
                mv "$dn/$bn" "$dn/${bn//.}"
        fi
done

しかし、私の状況は役に立たないようです。私のスクリプトはまだ ".@__thumb"フォルダを削除します。問題が何であるかを知っているか改善するアイデアはありますか?私の説明が明確かどうかわかりません。ご不明な点がございましたら、お気軽にお問い合わせください。とても感謝しています。

答え1

ここでは、あなたの質問で要求されているようにディレクトリ自体を削除するのではなく(あなたのコードが明らかにしようとしているように)、これらの隠されたディレクトリ名の先行点を削除したいとします。

ここでは以下を使用しますzsh

autoload -Uz zmv
zmv -n '(**/).(^@__thumb)(#qD/)' '$1$2'

満足すれば削除-n(テスト実行)します。

を使用するには、find次のものを使用できます。

LC_ALL=C find . -depth -name '.?*' ! -name '.@_thumb' -type d -exec sh -c '
  for file do
    base=${file##*/}
    mv -i -T "$file" "${file%/*}/${base#.}"
  done' sh {} +

mvGNUを想定-T

あなたのアプローチはそれほど強力ではなく、いくつかの問題があります。

  • 1行を読むには、read構文は次のとおりです。IFS= read -r line、いいえread line。ただし、ファイルパスはとにかく複数行で構成できます。findこのように出力を繰り返すことはできません。
  • -name '.*'.名前がで始まり、次のファイルと一致します。若い以上数値。したがって、それ自体が一致し、.ロケールで有効な文字を形成しないバイトシーケンスを含むファイル名をスキップします。したがって、LC_ALL=Cすべてのバイトが文字であることを確認し、.?*少なくとも1つの文字(LC_ALL=C次のバイト.)があることを確認してください。
  • [[ $a = $b ]]inはパターンと一致することをbash確認します(inの逆)。バイト間同等比較のための標準が必要です(ただし、ワイルドカードが含まれていないため、ここでは違いはありません)。$a$b!=[[ $a = "$b" ]][ "$a" = "$b" ].@__thumb
  • `...`は廃止された古代の形式のコマンド置換であるため、最新の形式を使用することをお勧めします$(...)。どちらも末尾の改行を削除するため、任意のファイル名で使用できないという問題があります。ディレクトリ名/デフォルト名+コマンド置換の代わりに標準のsh ${var##*/}AND演算子を使用すると、この問題を回避できます。${var%/*}
  • ksh演算子はin${bn//.}のすべてのエントリを削除します。したがって、最初の文字のみを削除するか、標準を使用して先行文字を削除するための名前が 。に変わります。.$bn.foo.dfood${bn/.}${bn#.}.
  • ディレクトリにa.foofoodirの両方が含まれている場合(移動しますmv .foo foo。 )mv .foo foo/.foo.foo 入力する(いいえ到着foo目次)。-Tこのような状況を回避し、使用を-i避ける機会を提供します。すべての健全性チェックは、作業を実行する前に実行されるため、より安全です。foo.foozmv
  • @RalfFriedlがすでに指摘したように、$bn設定する前に参照してください!
  • それにもかかわらず、.gitディレクトリ名を変更すると、その親ディレクトリgitgitもはやgitリポジトリと見なされなくなります。名前.bashrcを変更すると、起動時などに読み込まれなくなります。bashrcbash

答え2

これは通常プログラミングに関連していますが、コマンドの順序に注意する必要があります。

$bnここでは条件付き比較に値を使用しますが、後で値を計算します。

だから試してみてください

...
bn=`basename "$f"`
if [[ $bn != $thumb ]]
...

関連情報