Удалить начальные пробелы из файлов, папок и их подпапок

Удалить начальные пробелы из файлов, папок и их подпапок

Я придумал это, но, к сожалению, это не влияет ни на какие файлы/папки в подпапках.

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

Структура папок:

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

решение1

Переименование необходимо производить снизу вверх.

Проблема в том, что вам нужно переименовать каталоги.снизу вверх. В противном случае команда попытается переименовать файлы и каталоги, находящиеся внутри уже перемещенных (переименованных) папок, и, таким образом, больше не сможет их найти.

Здесь можно использовать python's в сочетании с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и 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)"

Связанный контент