На этот вопрос уже есть ответ здесь:
У меня есть структура каталогов, подобная этой
file 1.ext1
file 1.ext2
file 1.ext3
file 2.temp.ext1
file 2.ext2
file 3.ext1
Я хочу создать каждую подпапку и переместить имя каждого файла независимо от того, какое расширение там
file 1\file 1.ext1
file 1\file 1.ext2
file 1\file 1.ext3
file 2\file 2.temp.ext1
file 2\file 2.ext2
file 3\file 3.ext1
любой простой способ сделать это? спасибо
find . -type f -exec sh -c 'base=$(echo $1 | grep -oP "(?<=\./).*(?=\.[^\.]*$)"); mkdir -p "${base}"; mv "$1" "$base"' . {} \;
find . -type f
Этот сценарий будет воздействовать на все "регулярные" файлы (т.е. не будет работать над текущим каталогом .
).-exec sh -c '...' . {} \;
выполнитесь '...
'часть, с именем файла, питаемым к сценарию как аргумент (и получил доступ $1
).base=$(echo $1 | grep -oP "(?<=\./).*(?=\.[^\.]*$)");
получите основную часть имени файла. т.е. grep
часть после ./
и перед финалом .
.mkdir -p "${base}";
Создайте каталог (например. file1
).mv "$1" "$base"
Переместите файл в недавно созданный каталог.Если Вы предпочитаете файлы такой как file1.temp.ext1
перемещаться в каталог file1
, вместо file1.temp
, затем можно использовать следующее вместо этого.
find . -type f -exec sh -c 'base=$(echo $1 | grep -oP "(?<=\./)[^\.]*(?=\..*$)"); mkdir -p "${base}"; mv "$1" "$base"' . {} \;
(?<=\./)[^\.]*(?=\..*$)
Единственная часть, которая отличается, является регулярным выражением для получения "основной" части имени файла, где новый каталог будет создан. Это теперь получает до первого .
, вместо последнего .
.это будет достаточно:
#!/bin/bash
#this script sorts files according to their extensions
oldIFS=$IFS
IFS=\n'
(find . -type f) > /tmp/temp
for var in `cat /tmp/temp`
do
name=`basename "$var"`
name=`echo $name | cut -d'.' -f1`
mkdir -p $name
mv "$var" $name/ 2> /dev/null
done
IFS=$oldIFS