Переименование нескольких файлов с помощью xargs без использования цикла

find. -type d -exec sh -c '
    dirpath=$1
    set -- "$dirpath"/*.md
    [ -f "$dirpath/${dirpath##*/}.md" ] && [ "$#" -eq 1 ]' sh {} \; -print

Приведенный выше код найдет все каталоги ниже текущего каталога (, включая текущий каталог ), и для каждого из них будет выполнен короткий сценарий оболочки.

Шелл-код будет проверять, существует ли уцененный файл с тем же именем, что и у каталога внутри каталога, и является ли это единственным *.mdименем в этом каталоге. Если такой файл существует и если это единственное имя *.md, встроенный сценарий оболочки завершается с нулевым статусом выхода. В противном случае он завершается с не--нулевым статусом выхода (, сигнализируя о сбое ).

Бит set -- "$dirpath"/*.mdустановит позиционные параметры в список имен путей, соответствующих шаблону (соответствует любому имени с суффиксом .mdв каталоге ). Затем мы можем использовать $#позже, чтобы увидеть, сколько совпадений мы получили от этого.

Если сценарий оболочки завершится успешно, -printнапечатает путь к найденному каталогу.

Немного более быстрая версия, использующая меньше вызовов встроенного скрипта,но это не позволяет вам делать больше с найденными путями в самом find(хотя встроенный скрипт может быть дополнительно расширен):

find. -type d -exec sh -c '
    for dirpath do
        set -- "$dirpath"/*.md
        [ -f "$dirpath/${dirpath##*/}.md" ] &&
        [ "$#" -eq 1 ] &&
        printf "%s\n" "$dirpath"
    done' sh {} +

Те же команды, но не заботясь о том, есть ли другие .mdфайлы в каталогах:

find. -type d -exec sh -c '
    dirpath=$1
    [ -f "$dirpath/${dirpath##*/}.md" ]' sh {} \; -print
find. -type d -exec sh -c '
    for dirpath do
        [ -f "$dirpath/${dirpath##*/}.md" ] &&
        printf "%s\n" "$dirpath"
    done' sh {} +

См. также:

0
14.09.2021, 13:38
0 ответов

Теги

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