-1

I am creating a script that deletes files using the config which contains Folder and File_Prefix.

  • This will be the config file: config.txt

    /local/FolderA,App
    /local/FolderB,Log
    /local/FolderC,File
    
  • This is my script:

    file="local/config.txt"
    while IFS="," read -r folder prefix;
    do
        find %s -name %s* -type f -exec rm {} \ "$folder" "$prefix";
    done < "$file"
    

However it is not working properly. Can you help in troubleshooting? I am having troubling assigning the values from IFS command.

AdminBee
  • 21,637
  • 21
  • 47
  • 71
  • 1
    In general, replace `rm` with `echo rm` to see what the `find` is doing (if anything). When saying "it's not working" you really need to tell us the detail. What's happening? what's not happening that you think should be happening? What error messages are being output? What sort of "trouble assigning the values"? Have you tried a simple `echo "folder=$folder and prefix=$prefix."` command just above the `find` to check if the values are assigned as expected? – roaima May 26 '21 at 08:10
  • 1
    I've never seen this snytax: `some_command %s \ "value"` -- Which shell is that? Also, you forgot to quote `*`, it will expand to the files in your current directory. Having relative paths in a script is no good. -- In general: Do not use `rm` when testing scripts and you're not sure it works fine, bad things might happen. Rather use `rm -i` or `echo rm`. – pLumo May 26 '21 at 08:20
  • I notice that you have asked several questions by now but haven't accepted _any_ of the answers that you have received. Consider accepting the most helpful answers to each question. Doing so will mark the issue as resolved, and it will also increase your chances of getting help in the future. See also https://unix.stackexchange.com/help/someone-answers – Kusalananda Sep 23 '21 at 19:36

2 Answers2

3

Assuming your configuration file does not contain fields with embedded newlines or commas, and assuming that you want to delete all files that have the mentioned filename prefix in the designated directories only (i.e. not recursively):

#!/bin/sh

while IFS=, read -r directory prefix; do
    rm -- "$directory/$prefix"*
done <config.txt

This reads the first comma-delimited field on each line into the directory variable, and the rest of the line into the prefix variable. It then uses these to delete the files. (See Where is the `--` (double dash) argument documented? for an explanation about --)

If you need to do the deletion recursively, beneath each mentioned directory path:

#!/bin/sh

while IFS=, read -r directory prefix; do
    find "$directory" -name "$prefix*" -exec rm {} +
done <config.txt

The difference between these two, apart from find searching recursively, is that $prefix will be used as if it was a globbing pattern in the find command.

Note that * needs to be quoted when used with find so that the shell doesn't expand it to matching names in the current directory, and that * should be unquoted when used with rm in the first loop above, so that the shell expands it to all matching names.

If you don't want to do the deletion recursively, but you have so many files matching the generated patterns so that the first loop gives you an "argument list too long" error, then you may want to do an extra inner loop,

#!/bin/sh

while IFS=, read -r directory prefix; do
    for pathname in "$directory/$prefix"*; do
        rm -- "$pathname"
    done
done <config.txt

or use find restricted to the top-level search path,

#!/bin/sh

while IFS=, read -r directory prefix; do
    find "$directory" ! -path "$directory" -prune -name "$prefix*" -exec rm {} +
done <config.txt
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • thank you very much for your detailed reply! If I want to add another variable like 'Age' so that I can limit it to delete old messages, how can I add this in the code? Is it something like this: find "$directory" ! -path "$directory" -prune -name "$prefix*" -mtime +"$Age" -exec rm {} + – UnixDummy001 May 27 '21 at 06:25
  • @UnixDummy001 That looks about right, but test on a copy of your data first. – Kusalananda May 27 '21 at 06:48
2

We use xargs to pass on filepaths from config.txt file to a sh executable in its command line.

< config.txt xargs -rd'\n' sh -c '
for arg do
 find "${arg%,*}" \
    -name "${arg##*,}*" \
    -type f \
    -exec rm -f {} + ;
done
' xargs-sh
guest_7
  • 5,698
  • 1
  • 6
  • 13