Выравнивание вложенного каталога

StackApplet зависит от приложения индикатора. Это - Канонический проект, который упаковывается для Ubuntu, но не для Debian все же.

Существует предложение упаковать приложение индикатора для Debian, и проект Ayatana работает над ним, но пакету не удается создать в настоящий момент.

Тем временем можно попробовать один из следующих подходов:

  • Захватите зависимости из Ubuntu как двоичные пакеты: libappindicator0 и python-appindicator.
  • Захватите исходный пакет и попытайтесь перекомпилировать, надеясь, что Вы сможете решить безотносительно проблемы Ayatana, с которым встречаются.
  • Захватите источник StackApplet и компиляцию без частей, которые требуют приложения индикатора (чтения описания апплета “любой ПК Linux рабочий Gnome или поддержка AppIndicators”).

75
25.10.2012, 03:01
7 ответов

Можно сделать это с GNU find и GNU mv:

find /dir1 -mindepth 2 -type f -exec mv -t /dir1 -i '{}' +

В основном, путь, который работает если это find проходит все дерево каталогов и для каждого файла (-type f) это не находится в каталоге верхнего уровня (-mindepth 2), это выполняет a mv для перемещения его в каталог, Вы хотите (-exec mv … +). -t аргумент mv позволяет Вам указать целевой каталог сначала, который необходим потому что + форма -exec помещает все исходные местоположения в конце команды. -i делает mv спросите прежде, чем перезаписать любые дубликаты; можно занять место -f перезаписывать их, не спрашивая (или -n не спросить или перезаписать).

Как Stephane Chazelas указывает, вышеупомянутое только работает с инструментами GNU (которые являются стандартными на Linux, но не большинстве других систем). Следующее несколько медленнее (потому что оно вызывает mv многократно), но намного более универсальный:

find /dir1 -mindepth 2 -type f -exec mv -i '{}' /dir1 ';'
79
27.01.2020, 19:31
  • 1
    Отредактированный для использования -exec + так, чтобы это не выполняло большое количество процессов mv –  Random832 24.10.2012, 22:32
  • 2
    @Random832 И собирающийся возвращаться снова, потому что + не работает. mv нуждается в месте назначения, поскольку заключительный аргумент, но + имел бы источники как заключительный аргумент. Найдите, что привычка даже принимает синтаксис, на который Вы изменили ее (find: missing argument to `-exec') –  derobert 24.10.2012, 22:34
  • 3
    @Random832, но я предполагаю mv имеет a -t мы можем использовать, таким образом, я изменю его на это. –  derobert 24.10.2012, 22:36
  • 4
    @Dom find печать скрытые (точечные) файлы по умолчанию. Глубина относительно каталога, который Вы передаете для нахождения. –  derobert 15.07.2013, 18:32

Попытайтесь делать это:

cp /dir1/dir2/file{1,2} /another/place

или для каждого соответствия файлов file[0-9]* в subdir:

cp /dir1/dir2/file[0-9]* /another/place

См. http://mywiki.wooledge.org/glob

3
27.01.2020, 19:31
  • 1
    я должен был указать на это, но я имею во многие файлы для использования {} в моей настоящей проблеме. –  turtle 24.10.2012, 22:30
  • 2
    Посмотрите мое второе решение –  Gilles Quenot 24.10.2012, 22:31
  • 3
    , Отредактированное для использования -exec + так, чтобы это не выполняло большое количество процессов mv ---------121 бинго--------10273----. Спасибо за справку. Это - определенно лучшее решение. –  turtle 24.10.2012, 22:34

В zsh:

mv dir1/*/**/*(.D) dir1

**/ подкаталоги пересечений рекурсивно. Спецификатор шарика . соответствия регулярные файлы только, и D гарантирует, что точечные файлы включены (по умолчанию, файлы, имя которых запускается с a . исключены из подстановочных соответствий). Для чистки теперь пустых каталогов впоследствии работать rmdir dir1/**/*(/Dod)/ ограничивает каталогами, и od заказывает глубину соответствий сначала, чтобы удалить dir1/dir2/dir3 прежде dir1/dir2.

Если общая длина имен файлов является очень большой, можно столкнуться с ограничением на длину командной строки. Zsh имеет builtins для mv и rmdir которые не затронуты этим ограничением: выполненный zmodload zsh/files включить им.

Только с инструментами POSIX:

find dir1 -type f -exec mv {} dir1 \;
find dir1 -depth -exec rmdir {} \;

или (быстрее, потому что это не должно выполнять отдельный процесс для каждого файла),

find dir1 -type f -exec sh -c 'mv "$@" dir1' _ {} +
find dir1 -depth -exec rmdir {} +
36
27.01.2020, 19:31
  • 1
    Это должно быть принятым ответом! Особенно с краткой zsh версией. –  Adamski 06.09.2017, 13:18

Я написал две функции, которые можно использовать вместе и которые делают именно это, вы можете ограничить уровень каталога, добавив параметр -maxdepth $VAL.

# This scripts flattens the file directory
# Run this script with a folder as parameter:
# $ path/to/script path/to/folder

#!/bin/bash

rmEmptyDirs(){
    local DIR="$1"
    for dir in "$DIR"/*/
    do
        [ -d "${dir}" ] || continue # if not a directory, skip
        dir=${dir%*/}
        if [ "$(ls -A "$dir")" ]; then
            rmEmptyDirs "$dir"
        else
            rmdir "$dir"
        fi
    done
    if [ "$(ls -A "$DIR")" ]; then
        rmEmptyDirs "$DIR"
    fi
}

flattenDir(){
    local DIR="$1"
    find "$DIR" -mindepth 2 -type f -exec mv -i '{}' "$DIR" ';'
}

read -p "Do you wish to flatten folder: ${1}? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    flattenDir "$1" &
    rmEmptyDirs "$1" &
    echo "Done";
fi
2
27.01.2020, 19:31

Расширение популярного ответа на этот вопрос, так как у меня был -пример использования для выравнивания каталога, содержащего файлы с таким же именем.

dir1/
├── dir2
│   └── file
└── dir3
    └── file

В этом случае параметр -i(--interactive), переданный в mv, не даст желаемого результата для выравнивания структуры каталогов и устранения конфликтов имен. Поэтому он просто заменяется на--backup=t(эквивалентным--backup=numbered). Дополнительная документация по опции-b(--backup)доступна по адресу https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options.

Результат:

find dir1/ -mindepth 2 -type f -exec mv -t dir1/ --backup=t '{}' +

Что дает:

dir1/
├── dir2
├── dir3
├── file
└── file.~1~
5
27.01.2020, 19:31

tar и zip могут включать, а затем удалять структуру каталогов, поэтому я смог быстро сгладить вложенный каталог с помощью

tar -cvf all.tar *

с последующим перемещением all.tar в новое место, затем

tar -xvf all.tar --strip=4

8
27.01.2020, 19:31

Оставаясь в dir1, вы можете просто сделать это с помощью mv dir2/*.. Если у вас есть больше подпапок на уровне dir2, вы можете использоватьmv */*.

3
06.05.2020, 17:58

Теги

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