5

Apologies if this is trivial- but how do list just one file in each subdirectory of my root folder? Linux terminal or MS DOS syntax doesn't matter. I would guess it would be an ls or dir command with some parameter but I havent found anything in the manual for either command.

4 Answers 4

2

If you want to see the directory names use -

ls -R1 | grep -A 1 ":"

If you DON'T want to see the directory names use -

ls -R1 | grep -A 1 ":" | grep -v ":"

2
  • You don't need -1 when piping: ls automatically gives one-column output when output is not a TTY. Jun 1, 2012 at 7:14
  • 1
    Also, : is a valid file name character which would create extra matches, and file names with embedded newlines won't be handled. Jun 1, 2012 at 7:36
1

Following command do:

for d in `find / -maxdepth 1 -mindepth 1 -type d`; do find $d -maxdepth 1 -type f | head -n1 ;done
0

Wrote a little script to do this.

#!/bin/bash
for dir in `find . -type d` # Find directories recursively
do
  # cd into directory, quotes are for directory names with spaces
  cd "$dir"             

  # Print out directory name
  echo "In directory $dir:"

  # Force list output to be one entry per line, pipe through inverted grep to 
  # exclude directories, pipe through awk to get the first item. You can specify
  # the number of files you want.     
  ls -p1 | grep -v / | awk -v "num_of_files=1" 'NR<=num_of_files { print $1 }'

  # cd back to root directory
  cd "$OLDPWD"              
done

Output:

In directory .:
test.sh
In directory ./bar:
barfile.txt
In directory ./baz:
bazfile.txt
In directory ./baz/quux:
something.txt
In directory ./foo:
foofile.txt
0
find -type d -print0 | xargs -0 ls | awk '/^\.\//||newdir{newdir=!newdir;print}'
  • find -type d gets all subdirectories to current directory.
  • -print0 and -0 takes care of problematic file names (spaces, newlines and such).
  • The cryptic awk command will continue if the line beginning matches ./ (which denotes directories) OR if the newdir variable is true. If it continues, newdir will be set to its opposite (i.e. true if it is false and vice versa) and print the line.

Some elaboration on the awk part: when a directory is encountered, newdir that by default is false (since it is not set) will be set to true and the directory will be printed. On the next line, ^\.\/ will not match, but newdir will now be true and the bracket will once again be run. Now newdir will be set to its opposite (false) and the line will be printed. Now no lines will be printed until the next directory comes up.

File names with embedded newlines will not be handled gracefully by awk in this example.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .