Найти с помощью mkdir и подстроки

locate буферизует поток STDOUT, вам необходимо сделать STDOUT для locate небуферизованным (или буферизованным по строке).

Если вы работаете в системе GNU, вы можете использовать stdbuf (поставляется с GNU coreutils ).

Чтобы сделать STDOUT locate небуферизованным:

stdbuf -o0 locate something | ...

Буферизованная строка:

stdbuf -oL locate something | ...

Проверьте man stdbuf , чтобы получить больше информации.

2
19.01.2017, 19:45
2 ответа

Я бы просто использовал для этого цикл bash:

for i in **/*.txt; do mkdir "${i%.txt}"; done

Если я запустил это в вашем примере, я получу:

$ tree
.
├── 1
│   └── 01-01-2015.txt
├── 2
│   └── 02-02-2016.txt
└── 3
    └── 03-03-2017.txt

3 directories, 3 files
$ shopt -s globstar
$ for i in **/*.txt; do mkdir "${i%.txt}"; done
terdon@oregano foo $ tree
.
├── 1
│   ├── 01-01-2015
│   └── 01-01-2015.txt
├── 2
│   ├── 02-02-2016
│   └── 02-02-2016.txt
└── 3
    ├── 03-03-2017
    └── 03-03-2017.txt

6 directories, 3 files

globstar - это опция bash, описанная в man bash :

globstar

Если установлено, шаблон ** , используемый в контексте раскрытия имени пути, будет соответствуют всем файлам и нулю или более каталогов и подкаталогов. Если за шаблоном следует / , совпадают только каталоги и подкаталоги.

Итак, после включения его с помощью shopt -s globstar шаблон ** / *. Txt найдет все файлы (или каталоги), имена которых заканчиваются на . txt .

$ {i% .txt} - это синтаксис оболочки для удаления подстроки. Общий формат - $ {variable% string} , и он удалит первый экземпляр string из конца переменной. Итак, $ {i% .txt} " будет именем файла (включая родительские каталоги) за вычетом .txt . Поэтому [передав его в mkdir ] создаст нужный каталог.


Лично я считаю, что приведенный выше синтаксис намного проще, но вот как это сделать с помощью find :

find . -name '*.txt' -exec sh -c 'mkdir ${0%.txt}' {} \;

Здесь команда -exec {} заменит {} с каждым из результатов найти , а затем выполнить для него команду . Поскольку эта команда является вызовом sh -c , sh примет {} в качестве нулевого позиционного параметра, $ 0 . Итак, мы запускаем ту же замену оболочки, как описано выше, чтобы создать каталог.

3
27.01.2020, 21:52
find example -name \*.txt | sed 's/\.txt$//' | xargs -n 1 mkdir

Предупреждение: для этого необходимо, чтобы ваши пути не содержали символы новой строки.

Изменить: см. Комментарий Тердона, если вы используете инструменты GNU.

4
27.01.2020, 21:52

Теги

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