Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

If I have a directory full of files and sub directories. What is the best way to list just the regular files which fall alphabetically before a given string?

Currently the best I can do using bash is the following:

for x in `find . -maxdepth 1 -type f | sort`
   if [[ "$x" > './reference' ]]

   echo $x

I feel like there is a more concise way to do this, but I'm not sure what it is. Any ideas?

share|improve this question
up vote 4 down vote accepted

if you need all of them

 find . -maxdepth 1 -type f | sort |  awk '$0 > "./reference"'

if you need the first

 find . -maxdepth 1 -type f | sort |  awk '$0 > "./reference"{print;exit}'
share|improve this answer
Thanks! A variation on this for getting all the files between the given variables would be: awk '$0 >= "'"${FROM}"'" && $0 <= "'"${TILL}"'"' – Nickolay Jun 22 '15 at 12:49

With sed it is more concise:

$ find -maxdepth 1 -type f | sort | sed '/^\.\/reference/,$d'

Which means (after sorting) delete the reference line (or greater) and all lines following to the last line.

The sed 'd' command is used here with an address range, where '/^./reference/' is the start and '$' is the end of the range. (And '$' as an address means the last line.)

share|improve this answer

Obligatory zsh answer, using the . glob qualifier to select only regular files and e to further select among matches:

echo *(.e\''[[ $REPLY > reference ]]'\')
share|improve this answer

eg. script-name "$HOME" "reference" ... find doesn't always output the leading ./, as in the case of find bin, or find /tmp. So if you only want the file base-names, this works.

update: Added tolower() to allow for a case insensitive comparison, which produces the alphabetical collation mentioned in the question...

dir="$1"; ref="$2"
find "$dir" -maxdepth 1 -type f -printf "%f\n" | awk -v"ref=$ref" 'tolower($0) < tolower(ref)'

Just pipe it to sort after awk, if you need it sorted.

share|improve this answer
This doesn't seem to work. I changed the last part of the awk script to be $0 < ref and that works, but since there are no spaces in the output of find the $2 field doesn't exist. Am I missing something? – Mike Deck Jul 25 '12 at 22:32
Thanks, I made a quick change to it at the last moment, and missed that field (it originally had two \xFF delimited fields)... Now, that I've had a bit of sleep, I can see that it is not handling case properly. I assume that as the question refers to an alphabetical collation, it means case insensitive. I have updated the answer. – Peter.O Jul 26 '12 at 0:52

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.