Переименуйте файл в имя родительского каталога в терминале

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

fred/result.txt
john/result.txt
mary/result.txt
...

В настоящее время я использую следующую команду для обработки каждого из эти файлы:

find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c \"cd '{}' && processResult result.txt\" \;

Я ищу что-то, что я могу добавить в конце этой команды, которая изменит имена файлов на fred.txt и т. д., а затем переместит файл в родительский каталог, чтобы устранить дополнительный слой каталогов.

Каким будет лучший способ сделать это?

1
задан 17 March 2016 в 01:30

4 ответа

Я думаю, что это законно (с использованием команды rename на основе perl]

find dir -name 'results.txt' -exec rename -nv -- 's|/(.*)/(.*)$|/$1/$1.txt|' {} +

, например.

$ tree dir
dir
├── fred
│   └── results.txt
├── john
│   └── results.txt
└── mary
    └── results.txt

3 directories, 3 files

, затем

$ find dir -name 'results.txt' -exec rename -v -- 's|/(.*)/(.*)$|/$1/$1.txt|' {} +
dir/fred/results.txt renamed as dir/fred/fred.txt
dir/john/results.txt renamed as dir/john/john.txt
dir/mary/results.txt renamed as dir/mary/mary.txt

, в результате чего

$ tree dir
dir
├── fred
│   └── fred.txt
├── john
│   └── john.txt
└── mary
    └── mary.txt

3 directories, 3 files

Если вам нужно только перейти на 1 уровень ниже dir, вы можете просто выполнить

rename -vn -- 's|/(.*)/(.*)$|/$1/$1.txt|' dir/*/results.txt

Как всегда, опция -n остается в целях тестирования

3
ответ дан 23 May 2018 в 12:48

Маленький скрипт python ниже будет делать то, что вы описываете; он будет:

переименовать любой файл в заданной директории с именем results.txt, в соответствии с его превосходным каталогом переместите его на один уровень (каталог), удалив каталог (теперь пустой), где первоначально был найден файл

Результат:

Это:

directory
|
├── fred
│   └── results.txt
├── john
│   └── results.txt
└── mary
    └── results.txt

станет:

directory
|
├── fred.txt
│   
├── john.txt
│ 
└── mary.txt

Сценарий

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

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    for file in files:
        if file == "results.txt":
            spl = root.split("/"); newname = spl[-1]; sup = ("/").join(spl[:-1])
            shutil.move(root+"/"+file, sup+"/"+newname+".txt"); shutil.rmtree(root)

Для использования

переименуйте любой файл в заданной директории с именем results.txt в соответствии с его старшим каталогом Запустите его командой:
python3 /path/to/move_rename.py <directory_to_reorganize>

] Обратите внимание на

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

3
ответ дан 23 May 2018 в 12:48

Выполнение этого поиска кажется чрезмерно сложным. Почему бы не использовать простой цикл?

for folder in *; do
    (cd "$folder" && processResult result.txt)  # This replaces your previous find(1)
    mv "$folder/result.txt" "${folder}.txt"
    rmdir "$folder"
done
2
ответ дан 23 May 2018 в 12:48

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

folder1/file1.txt file2.txt --> folder1/folder1.txt

Чтобы избежать этого, вы можете использовать эту команду или ее эквивалент:

for f in */*.txt ;do fp=$(dirname "$f"); fl=$(basename "$f"); mv "$fp/$fl" "$fp/$fp"_"$fl"; done

Сохраняя полное имя файла $ fl, а не только расширение, вы сохраняете все файлы .

folder1/file1.txt file2.txt --> folder1/folder1_file1.txt folder1_file2.txt
1
ответ дан 23 May 2018 в 12:48

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

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