Я бы сделал это за два прохода:
Во-первых, создайте каталоги, как вы сделали...
find -maxdepth 1 -type f \( -name "*.xxx" -o -name "*.yyy" \) \
| tr -s '[:blank:]' '_' \
| cut -d"-" -f1 \
| xargs mkdir -p
И второе использование скобки bash -расширения...
find. -maxdepth 1 -type d -not -name '.' -exec bash -c 'cp ${1}*.{xxx,yyy} ${1}/' _ {} \;
Результат:
$ tree
.
├── 519_RU
│ ├── 519_RU-1801013_20181217_141826_656.xxx
│ └── 519_RU-1801013_20181217_143011_657.xxx
├── 519_RU-1801013_20181217_141826_656.xxx
├── 519_RU-1801013_20181217_143011_657.xxx
├── 825_RU
│ └── 825_RU-1809008_20190723_015635_947.yyy
├── 825_RU-1809008_20190723_015635_947.yyy
└── AB47
Вы можете заменить in xxx yyy
командой, создающей список расширений.
Спасибо за помощь, наконец-то я нашел решение, основанное на другой теме, которая мне очень помогла(Здесь .
Пожалуйста, найдите его ниже:
find -maxdepth 1 -type f \( -name "*.xxx" -o -name "*.yyy" \) -size +0 -exec env file={} bash -c 'base="$(basename "$file" | tr -s '[:blank:]' '_' |cut -d"-" -f1)" ;dir="Out/${base%.*}";mkdir -p "$dir";cp "$file" "$dir" ; truncate "$file" -s 0 ' \;
Здесь было бы проще использовать специальные инструменты для переименования файлов, такие как prename
, mmv
или zsh
zmv
. Но если вам нужно использовать POSIX sh
и утилиты, я бы сделал что-то вроде:
find. ! -name. -prune \( -name '*.xxx' -o -name '*.yyy' \) -type f -exec sh -c '
ret=0
for file do
name=${file##*/}
dstdir=Out/$(printf "%s\n" "${name%%-*}" | tr -s "[:space:]" "[_*]")
mkdir -p "$dstdir" &&
cp "$file" "$dstdir/" &&
true > "$file" || ret=$?
done
exit "$ret"' sh {} +
(также избегая нескольких ваших GNUизмов ).