ツリー全体を通過し、一部(例:「.@__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 {} +
(mv
GNUを想定-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.d
food
${bn/.}
${bn#.}
.
- ディレクトリにa
.foo
とfoo
dirの両方が含まれている場合(移動しますmv .foo foo
。 )mv .foo foo/.foo
.foo
入力する(いいえ到着)foo
目次)。-T
このような状況を回避し、使用を-i
避ける機会を提供します。すべての健全性チェックは、作業を実行する前に実行されるため、より安全です。foo
.foo
zmv
- @RalfFriedlがすでに指摘したように、
$bn
設定する前に参照してください! - それにもかかわらず、
.git
ディレクトリ名を変更すると、その親ディレクトリgit
はgit
もはやgitリポジトリと見なされなくなります。名前.bashrc
を変更すると、起動時などに読み込まれなくなります。bashrc
bash
答え2
これは通常プログラミングに関連していますが、コマンドの順序に注意する必要があります。
$bn
ここでは条件付き比較に値を使用しますが、後で値を計算します。
だから試してみてください
...
bn=`basename "$f"`
if [[ $bn != $thumb ]]
...