次のファイルのリストがあります。
$ find .
.
./ sdf.sdf
./ dkfjd L
./aaa*
./aaa*bbb
./aaa:bbb
./b
./b/c
./b/c/xxx.123
これにより、rename -n -e 's/\*|\:/_/g' -e 's/^\ +//' *
私が欲しいものを手に入れることができます。
' sdf.sdf' would be renamed to 'sdf.sdf'
' dkfjd L' would be renamed to 'dkfjd L'
'aaa*' would be renamed to 'aaa_'
'aaa*bbb' would be renamed to 'aaa_bbb'
'aaa:bbb' would be renamed to 'aaa_bbb'
しかし、これを行うと、次のようなfind . | rename -n -e 's/\*|\:/_/g' -e 's/^\ +//'
結果が得られます。
Reading filenames from STDIN
'./aaa*' would be renamed to './aaa_'
'./aaa*bbb' would be renamed to './aaa_bbb'
'./aaa:bbb' would be renamed to './aaa_bbb'
2番目のコマンドでスペースで始まるディレクトリが表示されないのはなぜですか?
私もそうしてみましたが、find . -print0 | rename -n -0 -e 's/\*|\:/_/g' -e 's/^\ +//'
あまり違いはありませんでした。
大きなツリーで作業する必要がありますrename
。サブディレクトリに再帰する他の方法はありますか?
注:最終的にはmdfind
このオプションは使用できなくなるため、find
そのオプションは使用できません-exec
。
答え1
これにより、ファイルとディレクトリの名前が変更されます(実際には一致するすべての項目)。-depth
内容が安全に削除されるまで、より高いレベルのディレクトリ名が変更されないように指定しました。
find . -depth | rename -n -e 'y{*:}{_}; s{(?<=/)\s+(?!.*/.*$)}{}'
名前の変更は 2 つの RE で構成されます。 (私はrename
1つのパラメータしか受け入れないので、両方の操作を-e {RE}
1つのパラメータにリンクします。)
最初は簡単です。y{*:}{_}
代わりにorを使用してください(Unixとも呼ばれます)。*
:
_
tr
2番目はより複雑で、次のものを使用します。後ろを振り返って前を見て必要なコンポーネントを一致させます。これは、処理する式が\s+
直前になければならず、ファイル名の残りの部分には/
続いてはいけません。/
出力
rename(./ dkfjd L, ./dkfjd L)
rename(./aaa*, ./aaa_)
rename(./aaa*bbb, ./aaa_bbb)
rename(./ sdf.sdf, ./sdf.sdf)
rename(./aaa:bbb, ./aaa_bbb)