mmab
November 10, 2011, 10:58am
1
Here is a simplified example of my problem. Say I have the following 3 sub-directories;
./folder1
A.txt
A.sh
./folder2
B.txt
./folder3
C.txt
C.sh
I would like to list the directory names which contain both '.txt' & '.sh' type extensions. I have came up with the following code;
find . -type f \( -name "*.txt" -o -name "*.sh" \) -exec ls -l {} \; | sed 's/[^/]*$//'
This produces the following output;
./folder1/ (e.g ./folder1/A.txt)
./folder1/ (e.g ./folder1/A.sh)
./folder3/ (e.g ./folder3/C.txt)
./folder3/ (e.g ./folder3/C.sh)
This is a list of each directory for each instance of '.txt' and '.sh'. What I really want is only;
./folder1/
./folder3/
Would be great if this could all be done in the same line of code (find command). This is probably straight forward but I just cant seem to get it.
Thanks in advance.
Maybe this:
find . -type f \( -name "*.txt" -o -name "*.sh" \) -printf "%h\n" | sort -u
mmab
November 10, 2011, 11:18am
3
thanks for the quick response. I tried your method but got '-printf is not a valid option'. I tried it using just 'print' and got 'There is a missing conjunction'
How about this one:
find . -type f \( -name "*.txt" -o -name "*.sh" \) -exec dirname {} \; | sort -u
starting with your code fragment:
find . -type f \( -name "*.txt" -o -name "*.sh" \) -exec dirname {} \; | sort -u
mmab
November 10, 2011, 12:03pm
6
Tried the code but it now just outputs all the subdirectories in the main directory, regardless of the search criteria.
No way! What the command does is:
# Gets the result of the command below:
find . -type f \( -name "*.txt" -o -name "*.sh" \)
# And execute a:
dirname "<output line>"
A more verbose example:
find . -type f \( -name "*.txt" -o -name "*.sh" \) | xargs -t -I {} dirname "{}"
mmab
November 11, 2011, 5:39am
8
just tested it again, it works! Think I may have been putting in a rogue character.
Thanks
---------- Post updated 11-11-11 at 10:39 AM ---------- Previous update was 10-11-11 at 05:13 PM ----------
Ah, think i've found why I'm having problems. When I use the following code;
find . -type f \( -name "*.txt" -o -name "*.sh" \)
I get the output;
./folder1/A.txt
./folder1/A.sh
./folder2/B.txt
./folder3/C.txt
./folder3/C.sh
When I use your code;
find . -type f \( -name "*.txt" -o -name "*.sh" \) -exec dirname {} \; | sort -u
I get the output;
./folder1
./folder2
./folder3
So i'm just getting all the directories. The desired output is as follows (to eliminate any directory which doesn't contain 1 instance of both file extensions ;
./folder1
./folder3
Sorry if I was unclear before. Your help is appreciated.
Check this one:
# find ./folder* -type f \( -name "*.txt" -o -name "*.sh" \) -exec dirname {} \; | uniq -c | egrep '([ ]+ 2 .*)'
2 ./folder1
2 ./folder3
The final parse I let it to you! =o)