0

Would anyone be able to tell me why this for loop executes twice?
Thanks in advance.

    #!/bin/sh
    filesvar=$(find * -depth -name "*.exe" -o -name "*.bat" -type f)
    dir="$(dirname $filesvar)"
    for i in $dir
    do (
      cd $i
      cd ..
      rm -r "$(basename "${i}")"
    )
    done
CiaPan
  • 9,381
  • 2
  • 21
  • 35
  • 4
    Possibly you've got two dir names in the `$dir` variable...? Did you try to `echo` any data in use (either before the loop or inside it) to see why the script does what it does? – CiaPan Nov 23 '20 at 15:06
  • Yeah, you're right, I just checked and I have two dir names inside the variable. I'm not sure how to fix this though because in a single folder I've got two files, one with .exe and one with .bat extension so the find command scans the folder twice and gives the result twice, maybe you'd have some recommendation to fix this? – Gilmantas Morkus Nov 23 '20 at 15:16
  • 1
    Your error is *probably* that the command line is parsed into two parts with `-depth` applying to only one side of the `-o`. Perhaps try You are probably looking for `find . -depth \( -name "*.exe" -o -name "*.bat" \) -type f -exec echo rm -rf . \;` where I use `echo` as a placeholder. – tripleee Nov 23 '20 at 15:16
  • You may echo the directory list, splitting it on blanks into lines, and pipe through `sort` and `uniq` – the result should contain no duplicated. Be aware, however, it will fail **if** you ever have directories with a space character in the name... – CiaPan Nov 23 '20 at 15:20
  • BTW, shouldn't `cd ..` be done _after_ the `rm -r ...` command? – CiaPan Nov 23 '20 at 15:21
  • I want the script to delete any files that end with .exe and .bat, but also to delete the directory that those files were stored in. cd $i allows me to go into the folder where the files are located, but I need to move to a previous directory to be able to delete the directory that those files are in. Though I'm not sure if this is the best way of doing things since this is literally my first time using bash so I'm quite new to all of this. – Gilmantas Morkus Nov 23 '20 at 15:31

1 Answers1

0

Using find, sort and xargs from GNU CoreUtils:

find . -depth -name '*.exe' -o -name '*.bat' -printf '%h\0' |
  sort --zero-terminated --uniq |
    xargs --null -- echo rm -r --
  • GNU find supports -printf '%h\0' which will print the leading directory name followed by a null character.
  • sort --zero-terminated --uniq sorts the null delimited list stream while removing duplicates.
  • xargs --null -- transforms the null delimited entries onto arguments to the command.
  • echo rm -r -- executed by xargs to delete recursively. The echo turns this into a dummy to check the output. Remove the echo if the result matches your expectations.
Léa Gris
  • 17,497
  • 4
  • 32
  • 41