2

I have an alias rm='rm -irv' and I want to delete a bunch of files and/or directories but I only want 1 confirmation message like rm: descend into directory 'myfolder'?

I don't mind confirming for each directory but not for each file within each directory. The zsh feature for rm * or rm something/* works well but sometimes I am just deleting files rm *.txt or a single file rm document.txt but I would still like at least 1 confirmation.

This solution comes very close to what I'm looking for but does not work in every scenario. So let's say the directory "myfolder" contains 100 files then I would like something that looks like this:

~ > ls -F
myfolder/    empty.txt    file.txt    main.c

~ > rm *
zsh: sure you want to delete all 4 files in /home/user [yn]? n

~ > rm myfolder
rm: descend into directory 'myfolder'? y
removed 'file1.txt'
removed 'file2.txt'
...
removed 'file100.txt'
removed directory 'myfolder'

~ > rm main.c
rm: remove regular file 'main.c'? y
removed 'main.c'

~> rm *.txt
rm: remove all '*.txt' files? y
removed 'empty.txt'
removed 'file.txt'
6
  • That's a lot to ask for. How about you writing the code for that yourself first and then come ask about the parts that you can't figure out for yourself? Dec 18, 2020 at 16:55
  • @MarlonRichert I was hoping it wouldn't need a hefty script but instead a command that works in a similar way to rm which allows for one confirmation before deletion. I've searched but no luck 'cause most solutions are closer to rm -rf using the find command. At the moment all I've got is rm -irv and that's the closest to my desired behaviour and I wouldn't know how to even check for different input arguments like comparing a single file, multiple files, a dir, multiple dirs or a wildcard within a file/dir name. So maybe there are already zsh specific ways to achieve this behaviour.
    – ntruter42
    Dec 18, 2020 at 22:56
  • What makes it complicated is that you want to treat wildcards, directories, files and wildcards with filename extensions in different ways. That adds a significant amount of complexity. A bit too much for one question. Dec 19, 2020 at 10:40
  • @MarlonRichert Which is exactly why I was hoping it was supported natively by some command other than rm. A single confirmation for any deletion - that is all I'm looking for. How would you suppose I go about solving this in multiple questions?
    – ntruter42
    Dec 21, 2020 at 7:22
  • 1
    I added an answer that will get you very close. Dec 24, 2020 at 21:41

1 Answer 1

2

Getting the exact prompting and output listed in your question is practically impossible (or an insane amount of work), but the following should have you covered for all practical purposes:

# Disable the default prompt that says
# 'zsh: sure you want to delete all 4 files in /home/user [yn]?'
setopt rmstarsilent

# For portability, use the `zf_rm` builtin instead of any external `rm` command.
zmodload -Fa zsh/files b:zf_rm

rm() {
  # For portability, reset all options (in this function only).
  emulate -L zsh

  # Divide the files into dirs and other files.
  # $^ treats the array as a brace expansion.
  # (N) eliminates non-existing matches.
  # (-/) matches dirs, incl. symlinks pointing to dirs.
  # (-^/) matches everything else.
  # (T) appends file type markers to the file names.
  local -a dirs=( $^@(TN-/) ) files=( $^@(TN-^/) )

  # Tell the user how many dirs and files would be deleted.
  print "Sure you want to delete these $#dirs dirs and $#files files in $PWD?"

  # List the files in columns à la `ls`, dirs first.
  print -c - $dirs $files

  # Prompt the user to confirm.
  # If `y`, delete the files.
  #   -f skips any confirmation.
  #   -r recurses into directories.
  #   -s makes sure we don't accidentally the whole thing.
  # If this succeeds, print a confirmation.
  read -q "?[yn] " &&
      zf_rm -frs - $@ && 
      print -l '' "$#dirs dirs and $#files files deleted from $PWD."
}

For more info on zf_rm, see http://zsh.sourceforge.net/Doc/Release/Zsh-Modules.html#The-zsh_002ffiles-Module

More info on glob qualifiers (TN-^/) can be found here: http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers

3
  • Oh wow, that's incredible! It does exactly what I want, works better than I expected and I like the way it lists the files in columns and rows before confirmation instead of rows only after confirmation like default rm -v behaviour. How do I delete dirs only? rm */ does select folders but it shows up as files in the confirmation message and does not get removed after pressing y. It's printed as folder// so I'm assuming the zf_rm tries to delete folder// instead of folder/.
    – ntruter42
    Dec 25, 2020 at 3:38
  • 1
    @ntruter42 Like it says in the code comments, (-/) matches dirs only. So, just do rm *(-/). Dec 25, 2020 at 9:45
  • 1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .