Мне приходится иметь дело с большим количеством файлов, вложенных внутри каталогов (по одному файлу в каталоге), наподобие следующего:
fred/result.txt
john/result.txt
mary/result.txt
...
В настоящее время я использую следующую команду для обработки каждого из эти файлы:
find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c \"cd '{}' && processResult result.txt\" \;
Я ищу что-то, что я могу добавить в конце этой команды, которая изменит имена файлов на fred.txt и т. д., а затем переместит файл в родительский каталог, чтобы устранить дополнительный слой каталогов.
Каким будет лучший способ сделать это?
Я думаю, что это законно (с использованием команды 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 остается в целях тестирования
Маленький скрипт 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)
python3 /path/to/move_rename.py <directory_to_reorganize>
, как всегда, сначала проверьте его на маленьком образце
Выполнение этого поиска кажется чрезмерно сложным. Почему бы не использовать простой цикл?
for folder in *; do
(cd "$folder" && processResult result.txt) # This replaces your previous find(1)
mv "$folder/result.txt" "${folder}.txt"
rmdir "$folder"
done
Если у вас несколько файлов в папках с одинаковыми расширениями, некоторые из вышеперечисленных команд будут перезаписывать все, кроме одного, переименование всех файлов с тем же именем.
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