command line find first file in a directory

38,927

Solution 1

You can go inside each dir and run:

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

Solution 2

If first means whatever the shell glob finds first (lexical, but probably affected by LC_COLLATE), then this should work:

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

Proof of concept:

$ 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

Solution 3

Look for all first level directories, identify first file in this directory and then move it one level up

find . -type d \! -name . -prune | while read d; do
    f=$(ls $d | head -1)
    mv $d/$f .
done
Share:
38,927
Admin
Author by

Admin

Updated on August 13, 2020

Comments

  • Admin
    Admin almost 4 years

    My directory structure is as follows

    Directory1\file1.jpg
              \file2.jpg
              \file3.jpg
    
    Directory2\anotherfile1.jpg
              \anotherfile2.jpg
              \anotherfile3.jpg
    
    Directory3\yetanotherfile1.jpg
              \yetanotherfile2.jpg
              \yetanotherfile3.jpg
    

    I'm trying to use the command line in a bash shell on ubuntu to take the first file from each directory and rename it to the directory name and move it up one level so it sits alongside the directory.

    In the above example:

    • file1.jpg would be renamed to Directory1.jpg and placed alongside the folder Directory1

    • anotherfile1.jpg would be renamed to Directory2.jpg and placed alongside the folder Directory2

    • yetanotherfile1.jpg would be renamed to Directory3.jpg and placed alongside the folder Directory3

    I've tried using:

    find . -name "*.jpg"
    

    but it does not list the files in sequential order (I need the first file).

    This line:

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

    lists the files in the correct order but how do I pick just the first file in each directory and move it up one level?

    Any help would be appreciated!

    Edit: When I refer to the first file what I mean is each jpg is numbered from 0 to however many files in that folder - for example: file1, file2...... file34, file35 etc... Another thing to mention is the format of the files is random, so the numbering might start at 0 or 1a or 1b etc...

  • Cyril Graze
    Cyril Graze about 7 years
    simple and Unixy, I like
  • phuclv
    phuclv about 6 years
  • Cyril Graze
    Cyril Graze about 6 years
    Hi @LưuVĩnhPhúc, thanks for the link. The article makes a good point. In my case however, the filenames were all auto-generated and following a very specific predefined format. So the edge cases the article warns about don't really apply. In general cases, yes, probably not a good idea. Thanks!