У меня есть тысячи файлов в одной папке. Я хочу поместить файлы с таким же префиксом в папку с именем, совпадающим с именем префикса.
-folder
-a_1.txt
-a_2.txt
-a_3.txt
-b_1.txt
-b_2.txt
-b_3.txt
Я хочу, чтобы вывод был таким:
-a
-1.txt
-2.txt
-3.txt
-b
-1.txt
-2.txt
-3.txt
Использовать find -exec
:
find folder -name "*.txt" \
-exec sh -c 'f="$(basename "$1")"; mkdir -p "${f%%_*}"; mv "$1" "${f%%_*}"/"${f#*_}"' find-sh {} \;
Если у Вас есть несколько _
в имени файла. Это сократит после первого _
.
Подкачка f%%
+ f#
кому: f%
+ f##
если Вы хотите сократить после последнего _
вместо этого.
Это - сценарий Python, который перемещает a_1.txt, a_2.txt, a_3.txt к папке, названной a, и перемещает b_1.txt, b_3.txt к папке, названной b, но это сохраняет имена, как они:
# Import the needed packages
import glob
import shutil
import os
import re
import sys
def copy_(file_path, dest):
try:
# get the prfix from the filepath
pref = re.search(r'(.*)_\d*', file_path).group(1)
# Check if the folder already exists and create it if not
if not os.path.exists(dest + '/' + pref.split('/')[-1]):
os.makedirs(dest + '/' + pref.split('/')[-1])
# copy the file to the folder
shutil.move(file_path,
dest + '/' + pref.split('/')[-1] + '/' + file_path.split('/')[-1])
except Exception as e:
print(e)
print('there was a problem copying {} to the directory'.format(file_path))
pass
# Set the directory containing the folders
dirname = sys.argv[1]
# Set the directory that you want to create the folders in
dest = sys.argv[2]
for filepath in glob.glob(dirname + '/**'):
copy_(filepath, dest)
Для запущения скрипта сохраните его к file.py
затем выполните его использование python file.py dir1 dir2
где dir1 является папкой, где Ваши файлы существуют, и dir2 является папкой, где Вы хотите сохранить новые папки
Прежде:
dir1
├── a_1.txt
├── a_2.txt,
├── a_3.txt
├── b_1.txt
├── b_2.txt,
└── b_3.txt
После:
dir2
├── a
│ ├── a_1.txt
│ ├── a_2.txt,
│ └── a_3.txt
└── b
├── b_1.txt
├── b_2.txt,
└── b_3.txt
Создайте сценарий оболочки удара как:
#!/bin/bash
# Prefix length of the file in chars 1...x
PREFIXLENGTH=1
for file in *.txt
do
# define the folder name
prefix=${file:0:$PREFIXLENGTH}
# always mkdir here and fetch the error message
# can also be made with an if..then
mkdir $prefix 2>/dev/null
# split the rest of the file and move it to folder
mv "$file" "$prefix/${file:$PREFIXLENGTH}"
done
При вызове его в каталоге списка файлов он дает затем:
$ ls a b
a:
_1.txt _2.txt _3.txt
b:
_1.txt _2.txt _3.txt