나는 이것을 생각해 냈지만 불행히도 하위 폴더의 파일/폴더에는 영향을 미치지 않습니다.
find . -exec rename "s/^\s+//" {} \;
폴더 구조:
foo
|-- \ bar
`-- \ foo1
|-- \ bar1
`-- \ foo2
`-- \ bar2
답변1
이름 바꾸기는 아래에서 위로 이루어져야 합니다.
문제는 디렉토리 이름을 바꿔야한다는 것입니다아래에서 위로. 그렇지 않으면 명령은 이미 이동된(이름이 변경된) 폴더 내에 있는 파일 및 디렉터리의 이름을 바꾸려고 시도하므로 더 이상 찾을 수 없습니다.
여기서는 python
을 다음 os.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
and 를 사용하여 이 문제를 해결하는 방법에는 여러 가지가 있습니다 . 아마도 가장 안전한 방법은 모든 경로 구성 요소가 로 줄어들도록 대신 rename
사용 하고 패턴을 바꾸는 것입니다.-execdir
-exec
./
\./\s+
또한 디렉토리 이름을 바꾸는 경우이름을 바꿀 다른 파일/디렉토리의 조상을 포함할 수도 있음, 그런 다음 깊이 우선 순회를 수행해야 합니다.
종합해보면,
find . -depth -name ' *' -execdir rename -vn -- 's#\./\s+##' {} +
또는 (기능적으로 동일하지만 무슨 일이 일어나고 있는지 확인하기가 조금 더 쉽습니다) 경로 구분 기호에 길이가 0인 "뒤돌아보기"를 사용합니다.
$ 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)"