Переименовать файлы, добавив имя их родительской папки

Я хочу переименовать имя файла с именем его родительской папки, добавив имя папки перед текущим именем.

Например:

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

SOCH NC KT 633-ROYAL BLUE-MULTI
|
| 1.jpg
|
| 2.jpg
|
| 3.jpg

Ожидаемый результат

SOCH NC KT 633-ROYAL BLUE-MULTI
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg
|
|_SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg

SOCH NC KT 710-BLACK-MULTI

Кто-нибудь может посоветовать, как это можно сделать в файле .sh? Есть ли какая-либо утилита для выполнения операции?

6
задан 7 February 2018 в 10:24

6 ответов

В маленьком сценарии Python, переименовывая файлы рекурсивно (папки, а также sub папки):

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    for f in files:
        shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)

Как использовать

  • Скопируйте сценарий в пустой файл, сохраните его как rename_files.py
  • Выполните его с каталогом как аргумент:

    python3 /path/to/rename_files.py /directory/with/files
    

Примечание:

Как всегда, сначала примерьте образец!

Объяснение

Сценарий:

  • Обходы через каталоги, ища файлы.
  • Если файлы найдены, это разделяет путь к файлу с разделителем "/", сохраняя последнее в строке (который является именем папки родителя), чтобы быть вставленным перед именем файла:

    root.split("/")[-1]
    
  • Впоследствии, переместите файл в переименованный:

    shutil.move(root+"/"+f, root+"/"+root.split("/")[-1]+f)
    
5
ответ дан 7 February 2018 в 20:24
  • 1
    Добро пожаловать для Выяснения у Ubuntu! Я рекомендую редактирование этот ответ развернуть его с определенными деталями о том, как сделать это. (См. также , Как я пишу хороший ответ? для общих рекомендаций о том, на чем виды ответов считают самыми ценными, Спрашивают Ubuntu.) – David Foerster 10 December 2017 в 23:51

Вот небольшой пример того, как это может быть сделано, формируют каталог, который Вы хотите отредактировать.

$> ls                                                                          
file1.txt  file2.txt  file3.txt
$> pwd
/home/xieerqi/testing_dir
$> find . -type f -printf "%f\0" | \                                           
> while IFS="" read -d "" filename ; do \                                      
> echo $filename ${PWD##*/}_$filename   ; done
file2.txt testing_dir_file2.txt
file1.txt testing_dir_file1.txt
file3.txt testing_dir_file3.txt

Замена echo с mv или cp для копирования или перемещения по мере необходимости

1
ответ дан 7 February 2018 в 20:24
  • 1
    Просто поняв, что теперь я вижу принтер, но это определенно can' t печать. Вы знаете то, что могло бы вызывать это - я вижу, что это было проблемой с исходным сообщением, я отправил вопрос по ошибке как ответ, но ссылка они дают на том ответе doesn' t больше работают – Donal O'Cofaigh 2 September 2017 в 11:22

Решение для Bash, выполняющееся от папки, где имена файлов Вы хотите измениться, помещается. Необходимо измениться workdir на путь

#!/bin/bash

shopt -s globstar

workdir="/path/to/your/dir"

for folder in $workdir/**/*;do
  if [[ -d "$folder" ]]; then
    for file in "$folder"/*;do
        if [[ -f "$file" ]]; then
            fi="`basename "$file"`"
            fo="`basename "$folder"`"
            mv "$file" "$folder/$fo$fi"
        fi
    done
  fi
done

, Он изменится все файлы в все каталоги рекурсивно от workdir.

0
ответ дан 7 February 2018 в 20:24
  • 1
    Не перезагрузили улучшения. Я могу распечатать тестовые страницы от принтера, но не от компьютера. Все I' m печатающий от компьютера просто пробегает - но there' s без проблем с чем-либо на самом принтере. Это, кажется, та же проблема как человек, у которого была проблема, которую я сначала записал своему комментарию. Я думаю, что была некоторая ошибка, когда я распаковал ее - как будет я узнавать это теперь I' ve перезагружается? – Donal O'Cofaigh 2 September 2017 в 11:44

Используя только окружают (bash) с небольшой справкой от mv:

#!/bin/bash
shopt -s globstar  ##globstar will let us match files recursively
files=( /foo/bar/**/*.jpg )  ##Array containing matched files, mention where to search and what files here
for i in "${files[@]}"; do 
    d="${i%/*}"  ##Parameter expansion, gets the path upto the parent directory
    d_="${d##*/}"  ##gets the name of parent directory
    f="${i##*/}"  ##gets the file name
        echo mv "$i" "$d"/"${d_}""$f"  ##renaming, remove echo after confirming what will be changed and you are good
done

Пример:

$ shopt -s globstar
$ files=( /foo/bar/**/*.jpg )
$ for i in "${files[@]}"; do d="${i%/*}"; d_="${d##*/}"; f="${i##*/}"; echo mv "$i" "$d"/"${d_}""$f"; done
mv /foo/bar/KT/633-ROYAL/4.jpg /foo/bar/KT/633-ROYAL/633-ROYAL4.jpg
mv /foo/bar/KT/633-ROYAL/5.jpg /foo/bar/KT/633-ROYAL/633-ROYAL5.jpg
mv /foo/bar/KT/633-ROYAL/6.jpg /foo/bar/KT/633-ROYAL/633-ROYAL6.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/1.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI1.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/2.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI2.jpg
mv /foo/bar/KT/633-ROYAL/BLUE-MULTI/3.jpg /foo/bar/KT/633-ROYAL/BLUE-MULTI/BLUE-MULTI3.jpg
0
ответ дан 7 February 2018 в 20:24

Можно сделать это с rename:

rename -n 's/(.*)\//$1\/$1/' */*

Эта команда должна быть запущена в каталоге непосредственно выше каталогов, которые Вы хотите обработать. Это сначала только перечислит изменения для Вас для проверки, если Вы будете довольны результатами, выполненными это без -n выполнить переименование.

Пример выполняется

$ tree
.
└── SOCH NC KT 633-ROYAL BLUE-MULTI
    ├── 1.jpg
    ├── 2.jpg
    └── 3.jpg
$ rename 's/(.*)\//$1\/$1/' */*
$ tree
.
└── SOCH NC KT 633-ROYAL BLUE-MULTI
    ├── SOCH NC KT 633-ROYAL BLUE-MULTI1.jpg
    ├── SOCH NC KT 633-ROYAL BLUE-MULTI2.jpg
    └── SOCH NC KT 633-ROYAL BLUE-MULTI3.jpg

Объяснение

rename 's/(.*)\//$1\/$1/' */*
  • s/a/b/sзамена a b
  • (.*)\/ – возьмите все до (excl). последняя наклонная черта, сохраняющая его как группа 1 и замена он
  • $1\/$1 – группа 1 (имя dir), наклонная черта и группа 1 снова (префикс имени файла)
1
ответ дан 17 April 2019 в 05:29

Еще один подход только для удара, чтобы быть выполненным в папке, где файлы, которым нужно переименование, находятся:

for f in * ; do mv "$f" "$(basename "$(pwd)")"_"$f" ; done

Это также обработает имена файлов и имена папок с пробелами.

0
ответ дан 17 April 2019 в 05:29

Другие вопросы по тегам:

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