Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I need to gather a list of files and put this in a textfile. However, the files should not include their extension.

The command I have now without removing file extensions:

ls -1 /a/dir/*/dir/* > textfile

All selected files will have a an extension of .[a-z]{3}

(the reason I need this is because I need a list of unique base names, and unique will solve that after this step)

share|improve this question
    
Thanks for all the reactions! –  Peter Smit Jul 30 '09 at 11:57

8 Answers 8

up vote 3 down vote accepted

I always like to include a bash only solution:

for file in /a/dir/*/dir/*; do
    echo "${file%.*}" >> ~/file_list
done

and with an optional if statement to limit the file to your requested extension:

shopt -s extglob
for file in /a/dir/*/dir/*; do
    if [[ "$file" =~ \.[a-zA-Z]{3}$ ]]; then
        echo "${file%.*}" >> ~/file_list
    fi
done

In this similar serverfault question I explain the "${file%.*}" parameter expansion.

share|improve this answer

Something like that would list the file in the current directory removing everything after the first dot.

find . -maxdepth 1 -type f | xargs -iZ basename Z | cut -d"." -f1 > /tmp/resultfile

It would eventually have an issue with hidden files resulting in a blank line in the result file. Basename is here only to get rid of the "./" begining the filenames in the find result.

share|improve this answer

How about:

ls -1 /a/dir/*/dir/* | sed -e 's/\.[a-z]\{3\}$//'

Should do what you want.

share|improve this answer

It's much more simple than one thinks:

asd@locutus:~$ IZE=file.avi
asd@locutus:~$ echo $IZE
file.avi
asd@locutus:~$ echo ${IZE%%.???}
file
asd@locutus:~$ 

So in this manner:

ls -1 /a/dir/*/dir/* | while read VAR; do echo ${VAR%.???}; done

You can do whatever you want between do and done, echo is just an example.

man bash (Parameter Expansion):

   ${parameter%%word}
          The word is expanded to produce a pattern just as in pathname  expansion.
          If the pattern matches a trailing portion of the expanded value of param‐
          eter, then the result of the expansion is the expanded value of parameter
          with the shortest matching pattern (the ‘‘%’’ case) or the longest match‐
          ing pattern (the ‘‘%%’’ case) deleted.  If parameter is @ or *, the  pat‐
          tern  removal  operation is applied to each positional parameter in turn,
          and the expansion is the resultant list.  If parameter is an array  vari‐
          able subscripted with @ or *, the pattern removal operation is applied to
          each member of the array in turn, and  the  expansion  is  the  resultant
          list.

share|improve this answer
ls -1 /a/dir/*/dir/* | sed -e 's/\.[A-Za-z0-9]\{1-3\}$//' > textfile

Very similar to Russel Heillng's answer except it matches both lower and upper case, includes numbers in the extension and handles shorter (eg 2 character) examples.

share|improve this answer
    
/pattern/i would be more simpler for case insensitive matching, but bash parameter expansion is also a good start (see my answer) –  asdmin Jul 30 '09 at 17:54

You can also use cut like this :

for file in /a/dir/*/dir/* ; do
  echo \`echo $file | cut -d"." -f 1` >> textfile;
done

It will only work if you don't have any file or directories with a "." in the name

share|improve this answer

You have given an explicit definition for extensions,
But, the tags linux and bash-scripting suggest a unix environment.
Unless you are doing this with Cygwin on Windows.
These points may not matter in that case...

  • Be sure that you do not have numbers in your 'extension' (like md5)
  • Also, what about extensions with less than 3 characters? (script.sh)
  • What about extensions with upper case characters?
share|improve this answer
    
I match with my ls very specific files, a base name plus 4x an extension of 3 lowercase characters –  Peter Smit Jul 30 '09 at 11:57
    
@Peter, in which case, Russell's answer would have sufficed. ok. –  nik Jul 30 '09 at 16:12

A more generic answer, finds extensions of any length:

find . -type f | sed 's/^.*\.\([^.]*\)$/\1/'

I then use the following command to get a list of extensions in a dir:

find . -type f | sed 's/^.*\.\([^.]*\)$/\1/' | sort | uniq -c | sort -n
share|improve this answer

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.