5

I've a bash file on my project root with this line

$ ls | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

The above line removes all the .txt files from the project root but when I push all the .txt files to another folder e.g process_logs/ and try the same commands with ls, grep and rm its doesn't work.

This is what I tried but not worked to removed files on the process_logs directory.

 $ ls process_logs/ | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

N.B: I've also tried the command with simple regex pattern like ls process_logs/ | grep -P '^*.txt$' | xargs rm -f to remove files from directory but It doesn't work though.

3 Answers3

5

Try using find instead. If you don't want find to be recursive, you can use depth options:

find /process_logs -maxdepth 1 -mindepth 1 -type f -name 'some_shell_glob_pattern_here' -delete

Parsing the output of ls is not recommended because ls is not always accurate because ls prints a human-readable version of the filename, which may not match the actual filename. For more info see the parsing ls wiki article.

jordanm
  • 42,678
3

I agree with using find is the better option. But I want to add why your command is not working.

Your command:

$ ls process_logs/ | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

ls outputs filenames without the path. But you don't add the path to rm. So it will try to delete file names from your subdirectory in your current/ root directory.

Try

$ cd process_logs/; ls | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs rm -f

Or

$ ls process_logs/ | grep -P '^some_pattern_matching_regex_goeshere.txt$' | xargs -i rm -f "process_logs/{}"
pLumo
  • 22,565
1

If you have a simple shell filename globbing pattern, just use that.

E.g. (the * may be replaced by some more precise pattern),

rm -f process_logs/*.txt

or, if there are hundred of thousands of files, use xargs:

printf '%s\0' process_logs/*.txt | xargs -0 rm -f

If you absolutely need to use a regular expression, GNU find may do that with

find process_logs -maxdepth 1 -type f -regex '\.txt$' -delete

Note that the -regex predicate matches against the complete pathname, not just the filename portion at the end (which is why I anchored the expression to the end of the pathname with $). See also the -regextype option in the GNU find manual.

Kusalananda
  • 333,661