これを思いつきましたが、残念ながらサブフォルダー内のファイル/フォルダーには影響しません。
find . -exec rename "s/^\s+//" {} \;
フォルダ構造:
foo
|-- \ bar
`-- \ foo1
|-- \ bar1
`-- \ foo2
`-- \ bar2
答え1
名前の変更は下から上へ行う必要がある
問題は、ディレクトリの名前を変更する必要があることです下から上へそうでない場合、コマンドは既に移動された(名前が変更された)フォルダ内にあるファイルとディレクトリの名前を変更しようとするため、それらを見つけることができなくなります。
ここでpython
'sos.walk()
が使用され、topdown=False
短いスクリプトで説明すると:
#!/usr/bin/env python3
import os
import shutil
import sys
for root, dirs, files in os.walk(sys.argv[1], topdown=False):
for f in files:
if f.startswith(" "):
shutil.move(root+"/"+f, root+"/"+f.strip())
for dr in dirs:
if dr.startswith(" "):
shutil.move(root+"/"+dr, root+"/"+dr.strip())
使用するには
- スクリプトを空のファイルにコピーし、
no_space.py
次のコマンドで実行します:
python3 /path/to/no_space.py /path/to/directory/to/rename
答え2
^
他の回答でも指摘されているように、主な問題は、パス、ファイル名の先頭ではなく、 を使用します。find
と を使用する場合、これを回避する方法はいくつかあります。おそらく最も安全なのは、 の代わりにrename
を使用することです。これにより、すべてのパス要素が に縮小され、パターンが に置き換えられます。-execdir
-exec
./
\./\s+
また、ディレクトリの名前を変更する場合名前を変更する他のファイル/ディレクトリの祖先も含まれる可能性がある、深さ優先探索を実行する必要があります。
それを一緒に入れて、
find . -depth -name ' *' -execdir rename -vn -- 's#\./\s+##' {} +
または(機能的には同等だが、何が起こっているのかが少し分かりやすい)パス区切りに長さゼロの「後読み」を使用する
$ find . -depth -name ' *' -execdir rename -vn -- 's#(?<=\./)\s+##' {} +
./ bar2 renamed as ./bar2
./ foo2 renamed as ./foo2
./ bar1 renamed as ./bar1
./ foo1 renamed as ./foo1
./ bar renamed as ./bar
[注:-n
目的の動作が確実に実行されたら削除してください]
答え3
問題は、フルパスを含むfindの出力形式にあると思います。したがって、bar2の場合は次のようになります。
./ foo1/ foo2 /bar2
名前変更が正しく認識されません。
解決策としては、次のようにスクリプトを使用して各フォルダーを再帰的に実行することです。
#!/bin/bash
# if argument given consider it is the directory to parse
if [ -n "$1" ]; then
cd "$1"
fi
# rename all files in current folder
find . -maxdepth 1 -printf '%f\0' | xargs -0r -n 1 rename -nono 's/^\s+//'
# No, repeat for all subfolders with current script (we are in the subfolder)
find . -maxdepth 1 -type d -not -name '.' -print0 | xargs -0r -n 1 "$(readlink -f $0)"