Переместите несколько файлов в dir, если их имена содержат ту же строку, существующую на имя dir

У меня есть несколько файлов в одной папке:

ABA.xy
BEB.xy
ACA.xy

Те же файлы с другим расширением в другой папке

ABA.rr
BEB.rr
ACA.rr

Затем у меня есть единственная папка для каждого имени файла

ABA
BEB
ACA

Я хотел бы сделать следующее. если файл с расширением .xy и .rr имейте то же имя как папка, переместитесь в ту папку. Например,

ABA.xy and ABA.rr in ABA

Я знаком с mv но я думаю, что здесь должен записать маленький сценарий, чтобы сделать это.

5
задан 30 January 2015 в 04:40

2 ответа

Принятие файлов, хранивших в source dir и Ваши целевые папки находятся в dest как следующее дерево:

$ tree source
source
├── dir1
│   ├── ABA.xy
│   ├── ACA.xy
│   └── BEB.xy
└── dir2
    ├── ABA.rr
    ├── ACA.rr
    └── BEB.rr
2 directories, 6 files

$ tree dest
dest
├── ABA
├── ACA
└── BEB
3 directories, 0 files

Команда была бы:

find source -type f -exec sh -c 'noext="${0%.*}"; echo mv '{}' "dest/${noext##*/}/"' {} \;
  • source исходный каталог, или укажите родительский каталог.
  • noext="${0%.*}" разделяет расширение файлов и сохраняет результат в noext переменная.
  • "${noext##*/}" удаляет часть пути к файлу из noext переменная и погрузка единственное имя файла.

  • dest каталог является целевым родительским каталогом.

  • Так mv '{}' "dest/${noext##*/}/"' перемещает текущий файл в dest/$noext каталог.

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

Вот демонстрационный тест, которые показывают результат команды

Обратите внимание, что это управляет используемый echo для тестирования и пробного прогона. Если Вы удостоверяетесь о том, что Вы, делают, удаляют echo перед mv команда для выполнения фактического перемещения.

9
ответ дан 23 November 2019 в 08:48

Несколько иной подход с использованием rename:

rename 's#.*/(.+)(\.\w+)#mkdir "dest/$1"; "dest/$1/$1$2"#e' source/{a,b}/*

По сути, это просто использование регулярного выражения для перевода путей. Мы используем немного Perl (который поддерживает rename) для создания новых каталогов и переименования перемещает файл в конце.

Это не слишком умно. Он не будет искать случаи, когда нет соответствующего файла (мы могли бы искать и удалять каталоги только с одним файлом), и он, вероятно, взорвется, если будут файлы без расширений.

$ mkdir -p source/{a,b} dest
$ touch source/a/{ABA,BEB,ACA}.xy
$ touch source/b/{ABA,BEB,ACA}.rr
$ tree
.
├── dest
└── source
    ├── a
    │   ├── ABA.xy
    │   ├── ACA.xy
    │   └── BEB.xy
    └── b
        ├── ABA.rr
        ├── ACA.rr
        └── BEB.rr

$ rename 's#.*/(.+)(\.\w+)#mkdir "dest/$1"; "dest/$1/$1$2"#e' source/{a,b}/*
$ tree
.
├── dest
│   ├── ABA
│   │   ├── ABA.rr
│   │   └── ABA.xy
│   ├── ACA
│   │   ├── ACA.rr
│   │   └── ACA.xy
│   └── BEB
│       ├── BEB.rr
│       └── BEB.xy
└── source
    ├── a
    └── b
2
ответ дан 23 November 2019 в 08:48

Другие вопросы по тегам:

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