2

I m finding all files ending with .sh, but need to show only filenames and without ./

(find -type f \( -name "*[.sh]" \) ) 

it gives me all files ending with .sh and in subdirs too:

./erj.sh
./another/r5.sh
./another/t9.sh
./another/rrr2.sh
./elro/2039jlfsdjf.sh
./elro/tlr.sh
./elro/823.sh
./222.sh
./my_find_sh
./rrr.sh
./4234.sh
./sdf.sh

but using "cut -d. -f1" gives me empty output, because it takes first dot as remove point

find -type f \( -name "*[.sh]" \)  | cut -d. -f1

gives empty line.

Cyrus
  • 84,225
  • 14
  • 89
  • 153
ERJAN
  • 23,696
  • 23
  • 72
  • 146

3 Answers3

2

Try this:

find -type f \( -name "*.sh" \) -printf "%f\n"
sal
  • 3,515
  • 1
  • 10
  • 21
  • thx u but then i got wrong the files with names like "Q.shFB", "ER.HGZofZ.shEZ", "n.shU~.sh" – ERJAN May 23 '20 at 20:32
  • I updated the answer: the search parameter was not correct and included the files you show. – sal May 23 '20 at 20:36
  • thanks sal , but the ".sh" still matches filenames like "J.shjeG.sh.shqKcITpc", ".shHWn.shj" – ERJAN May 23 '20 at 20:39
  • 1
    Hey there. I don't see that: I added your exact filenames and they are not picked. I am on Ubuntu 20.04. I can also correctly do `find -type f -name *.sh -printf "%f\n"` and it doesn't match those spurious files. – sal May 23 '20 at 21:58
1

While the alternatives proposed by other users are completely right, in order to get the output you want strictly using the command you posted, you should pick the second field instead of the first one when using cut. Additionally, I don't think the parentheses are needed in that case at all, because it will make no difference.

That said, you can try:

find -type f -name "*.sh" | cut -d\. -f2
mtnezm
  • 1,009
  • 1
  • 7
  • 19
  • Ah of course. I interpreted the question as `cut` not being available or broken. Saying that I'm just masking my ignorance of `cut` ;-) – James Morris May 23 '20 at 21:32
  • thx u , but how do i detect file names like sk.CBlsLtz.sh.shs.shr.shKaU" – ERJAN May 24 '20 at 13:24
  • 1
    @ERJAN That case seems a different problem from this question. If you want, you can open a new one explaining your context with more details and the output you expect to get so we can take a further look at it. – mtnezm May 24 '20 at 17:27
  • @hads0m hell thx i thought "how can i edit the question and let others know it's a different question ? " ok i will make another question – ERJAN May 24 '20 at 18:17
0

Using find and Bash builtin string substitution:

find . -type f -name '*.sh' -printf "%P\n" | while read -r F; do echo ${F%.*}; done

Or with process subsitution for when you need to access variables created within the loop after the loop ends.

while IFS= read -r F; do echo "${F%.*}"; done < <(find . -type f -name '*.sh' -printf "%P\n")

"%P" removes the ./ while ${F%.*} removes the very last extension only. If you want everything after first period gone, ${F%%.*}.

Not clear in your question if you want path removed also, but if so, then wrap up ${F%.*} with a call to basename like so: $(basename "${F%.*}").

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
James Morris
  • 4,867
  • 3
  • 32
  • 51