Командной строке найти первый файл в каталоге

Моя структура каталогов выглядит следующим образом

Directory1\file1.jpg
          \file2.jpg
          \file3.jpg

Directory2\anotherfile1.jpg
          \anotherfile2.jpg
          \anotherfile3.jpg

Directory3\yetanotherfile1.jpg
          \yetanotherfile2.jpg
          \yetanotherfile3.jpg

Я пытаюсь использовать командную строку в оболочке bash на ubuntu, чтобы перенести первый файл из каждого каталога и переименовать его в имя каталога и переместить его на один уровень, чтобы он находился рядом с каталогом.

В приведенном выше примере:

  • file1.jpg будет переименован в Directory1.jpg и помещен рядом с папкой Directory1

  • anotherfile1.jpg будет переименован в Directory2.jpg и помещен рядом с папкой Directory2

  • yetanotherfile1.jpg будет переименован в Directory3.jpg и помещен рядом с папкой Directory3

Я пробовал использовать:

find . -name "*.jpg"

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

Эта строка:

find . -name "*.jpg" -type f -exec ls "{}" +;

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

Любая помощь будет оценена!

Изменить: когда я ссылаюсь на первый файл, я имею в виду, что каждый jpg пронумерован от 0 до любого количества файлов в этой папке - например: file1, file2...... file34, file35 и т.д.... Дело в том, что формат файлов случайный, поэтому нумерация может начинаться с 0 или 1a или 1b и т.д.

Ответ 1

Если сначала означает, что glob-оболочка находит первую (лексическую, но, вероятно, затронутую LC_COLLATE), тогда это должно работать:

for dir in */; do
    for file in "$dir"*.jpg; do
        echo mv "$file" "${file%/*}.jpg" # If it does what you want, remove the echo
        break 1
    done
done

Доказательство концепции:

$ mkdir dir{1,2,3} && touch dir{1,2,3}/file{1,2,3}.jpg
$ for dir in */; do for file in "$dir"*.jpg; do echo mv "$file" "${file%/*}.jpg"; break 1; done; done
mv dir1/file1.jpg dir1.jpg
mv dir2/file1.jpg dir2.jpg
mv dir3/file1.jpg dir3.jpg

Ответ 2

Вы можете войти в каждый каталог и запустить:

$ mv `ls | head -n 1` ..

Ответ 3

Найдите все каталоги первого уровня, определите первый файл в этом каталоге и затем переместите его на один уровень вверх

find . -type d \! -name . -prune | while read d; do
    f=$(ls $d | head -1)
    mv $d/$f .
done

Ответ 4

Основываясь на верхнем ответе, вот общая функция bash, которая просто возвращает первый путь, который разрешает файл в данном каталоге:

getFirstFile() {
    for dir in "$1"; do
        for file in "$dir"*; do
            if [ -f "$file" ]; then
                echo "$file"
                break 1
            fi
        done
    done
}

Использование:

# don't forget the trailing slash
getFirstFile ~/documents/

ПРИМЕЧАНИЕ: он ничего не вернет, если вы передадите ему неверный путь.