[英]Linux: Removing files that don't contain all the words specified
Inside a directory, how can I delete files that lack any of the words specified, so that only files that contain ALL the words are left?在目录中,如何删除缺少任何指定单词的文件,以便只留下包含所有单词的文件? I tried to write a simple bash shell script using grep and rm commands, but I got lost.
我尝试使用 grep 和 rm 命令编写一个简单的 bash shell 脚本,但我迷路了。 I am totally new to Linux, any help would be appreciated
我对 Linux 完全陌生,任何帮助将不胜感激
How about:怎么样:
grep -L foo *.txt | xargs rm
grep -L bar *.txt | xargs rm
If a file does not contain foo
, then the first line will remove it.如果文件不包含
foo
,则第一行将删除它。
If a file does not contain bar
, then the second line will remove it.如果文件不包含
bar
,则第二行将删除它。
Only files containing both foo
and bar
should be left只应保留同时包含
foo
和bar
的文件
-L, --files-without-match
Suppress normal output; instead print the name of each input
file from which no output would normally have been printed. The
scanning will stop on the first match.
See also @Mykola Golubyev's post for placing in a loop.另请参阅@Mykola Golubyev 的帖子,了解如何放置在一个循环中。
list=`Word1 Word2 Word3 Word4 Word5`
for word in $list
grep -L $word *.txt | xargs rm
done
Addition to the answers above: Use the newline character as delimiter to handle file names with spaces!除了上面的答案:使用换行符作为分隔符来处理带空格的文件名!
grep -L $word $file | xargs -d '\n' rm
grep -L word | grep -L字| xargs rm
xargs rm
To do the same matching filenames (not the contents of files as most of the solutions above) you can use the following:要执行相同的匹配文件名(不是上述大多数解决方案的文件内容),您可以使用以下内容:
for file in `ls --color=never | grep -ve "\(foo\|bar\)"`
do
rm $file
done
As per comments:根据评论:
for file in `ls`
shouldn't be used.不应该使用。 The below does the same thing without using the
ls
下面不使用
ls
做同样的事情
for file in *
do
if [ x`echo $file | grep -ve "\(test1\|test3\)"` == x ]; then
rm $file
fi
done
The -ve reverses the search for the regexp pattern for either foo or bar in the filename. -ve 反转对文件名中 foo 或 bar 的正则表达式模式的搜索。 Any further words to be added to the list need to be separated by \|
要添加到列表中的任何其他单词都需要用 \| 分隔。 eg one\|two\|three
例如一\|二\|三
First, remove the file-list:首先,删除文件列表:
rm flist
Then, for each of the words, add the file to the filelist if it contains that word:然后,对于每个单词,如果文件包含该单词,则将文件添加到文件列表中:
grep -l WORD * >>flist
Then sort, uniqify and get a count:然后排序,uniqify 并得到一个计数:
sort flist | uniq -c >flist_with_count
All those files in flsit_with_count that don't have the number of words should be deleted.应该删除 flsit_with_count 中没有字数的所有文件。 The format will be:
格式为:
2 file1
7 file2
8 file3
8 file4
If there were 8 words, then file1 and file2 should be deleted.如果有 8 个单词,那么 file1 和 file2 应该被删除。 I'll leave the writing/testing of the script to you.
我会把脚本的编写/测试留给你。
Okay, you convinced me, here's my script:好的,你说服了我,这是我的脚本:
#!/bin/bash
rm -rf flist
for word in fopen fclose main ; do
grep -l ${word} *.c >>flist
done
rm $(sort flist | uniq -c | awk '$1 != 3 {print $2} {}')
This removes the files in the directory that didn't have all three words:这将删除目录中不包含所有三个单词的文件:
You could try something like this but it may break if the patterns contain shell or grep meta characters:您可以尝试这样的事情,但如果模式包含shell或grep元字符,它可能会中断:
(in this example one two three are the patterns) (在这个例子中,一二三是模式)
for f in *; do
unset cmd
for p in one two three; do
cmd="fgrep \"$p\" \"$f\" && $cmd"
done
eval "$cmd" >/dev/null || rm "$f"
done
This will remove all files that doesn't contain words Ping or Sent这将删除所有不包含Ping或Sent字样的文件
grep -L 'Ping\|Sent' * | xargs rm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.