web-dev-qa-db-ja.com

ファイル、フォルダー、およびそれらのサブフォルダーから先頭の空白を削除します

これを思いつきましたが、残念ながらサブフォルダー内のファイル/フォルダーには影響しません。

find . -exec rename "s/^\s+//" {} \;

フォルダー構造:

foo
|-- \ bar
`-- \ foo1
    |-- \ bar1
    `-- \ foo2
        `-- \ bar2
4
Sascha

名前の変更は下から上に行う必要があります

問題は、ディレクトリの名前を変更する必要があることです下から上へ。そうでない場合、コマンドは既に移動(名前変更)されたフォルダー内にあるファイルとディレクトリの名前を変更しようとするため、それらを見つけることができなくなります。

pythonos.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
    
3
Jacob Vlijm

他の回答で述べたように、主な問題は、^がファイル名の先頭ではなく、pathの先頭を固定することです。 findrenameでそれを回避する方法はいくつかあります。おそらく最も安全なのは、-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を削除してください]

2
steeldriver

問題は、フルパスを含む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)"
1
Camilio