Как заменить пробелы в именах файлов с помощью сценария удара

Кто-либо может рекомендовать безопасному решению рекурсивно заменить пробелы символами нижнего подчеркивания в именах файлов и именах каталогов, начинающих с данного корневого каталога? Например:

$ tree
.
|-- a dir
|   `-- file with spaces.txt
`-- b dir
    |-- another file with spaces.txt
    `-- yet another file with spaces.pdf

становится:

$ tree
.
|-- a_dir
|   `-- file_with_spaces.txt
`-- b_dir
    |-- another_file_with_spaces.txt
    `-- yet_another_file_with_spaces.pdf
242
задан codeforester 6 May 2018 в 04:30
поделиться

5 ответов

Используйте переименовать (также известное как prename ), которое является сценарием Perl, который уже может быть в вашей системе. Сделайте это в два этапа:

find -name "* *" -type d | rename 's/ /_/g'    # do the directories first
find -name "* *" -type f | rename 's/ /_/g'

Основываясь на ответе Юргена и способном обрабатывать несколько уровней файлов и каталогов за одну границу, используя "Revision 1.5 1998/12/18 16:16:31 rmb1" версия / usr / bin / rename (сценарий Perl):

find /tmp/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \;
290
ответ дан 23 November 2019 в 03:12
поделиться

Решение найти / переименовать . переименование является частью util-linux.

Вам нужно сначала спуститься по глубине, потому что имя файла с пробелами может быть частью каталога с пробелами:

find /tmp/ -depth -name "* *" -execdir rename " " "_" "{}" ";"
11
ответ дан 23 November 2019 в 03:12
поделиться

bash 4.0

#!/bin/bash
shopt -s globstar
for file in **/*\ *
do 
    mv "$file" "${file// /_}"       
done
6
ответ дан 23 November 2019 в 03:12
поделиться
find . -depth -name '* *' \
| while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr ' ' _)" ; done

сначала не удалось понять это правильно, потому что я не думал о каталогах.

99
ответ дан 23 November 2019 в 03:12
поделиться

Вот (довольно подробное) решение find -exec, которое выводит предупреждения "файл уже существует" в stderr:

function trspace() {
   declare dir name bname dname newname replace_char
   [ $# -lt 1 -o $# -gt 2 ] && { echo "usage: trspace dir char"; return 1; }
   dir="${1}"
   replace_char="${2:-_}"
   find "${dir}" -xdev -depth -name $'*[ \t\r\n\v\f]*' -exec bash -c '
      for ((i=1; i<=$#; i++)); do
         name="${@:i:1}"
         dname="${name%/*}"
         bname="${name##*/}"
         newname="${dname}/${bname//[[:space:]]/${0}}"
         if [[ -e "${newname}" ]]; then
            echo "Warning: file already exists: ${newname}" 1>&2
         else
            mv "${name}" "${newname}"
         fi
      done
  ' "${replace_char}" '{}' +
}

trspace rootdir _
2
ответ дан 23 November 2019 в 03:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: