views:

939

answers:

4

If I have a BASH variable:

Exclude="somefile.txt anotherfile.txt"

How can I get the contents of a directory but exclude the above to files in the listing? I want to be able to do something like:

Files=  #some command here
someprogram ${Files}

someprogram should be given all of the files in a particular directory, except for those in the ${Exclude} variable. Modifying someprogram is not an option.

A: 

You can use find. something like:

FILES=`find /tmp/my_directory -type f -maxdepth 1 -name "*.txt" -not -name somefile.txt -not -name anotherfile.txt`

where /tmp/my_directory is the path you want to search.

You could build up the "-not -name blah -not -name blah2" list from Excludes if you want with a simple for loop...

ogrodnek
Is find portable across major unix-like platforms? BSD, Linux, etc.
dreamlax
+2  A: 

I'm not sure if you were taking about unix shell scripting, but here's a working example for bash:

#!/bin/bash

Exclude=("a" "b" "c")
Listing=(`ls -1Q`)

Files=( $(comm -23 <( printf "%s\n" "${Listing[@]}" ) <( printf "%s\n" "${Exclude[@]}"
) ) )

echo ${Files[@]}

Note that I enclosed every filename in Exclude with double quotes and added parenthesis around them. Replace echo with someprogram, change the ls command to the directory you'd like examined and you should have it working. The comm program is the key, here.

Hugo Peixoto
This seems like the simplest solution because it does not require a loop.
dreamlax
A: 

Here's a one liner for a standard Unix command line:

ls | grep -v "^${Exclude}$" | xargs

It does have one assumption. ${Exclude} needs to be properly escaped so charaters like period aren't interpreted as part of the regex.

Brian Pellin
That would work if I only had one file I wanted to exclude, but I could have up to 10 (but I don't want to place any arbitrary limit on excluded files).
dreamlax
A: 

Assuming filenames with no spaces or other pathological characters:

shopt -s extglob
Files=(!(@(${Exclude// /|})))
radoulov