Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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`
do
   if [[ "$x" > './reference' ]]
   then
      break
   fi

   echo $x
done

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
add comment

4 Answers

up vote 3 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
add comment

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
add comment

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...

#!/bin/bash
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
add comment

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
add comment

Your Answer

 
discard

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.