I am trying to find all occurrences of files which have a specified string in them and then clear out the contents of all those files. So a file with "stringtofind" within it would subsequently be an empty file.
To do this I have tried the following, but I get errors:
With the following I get error: find: missing argument to `-exec'
find / -maxdepth 1 -xdev -type f -exec grep -i "stringtofind" -l -exec sed -i '/./d'
With the following I get error:
grep: /nis
/tset.any
/test2.file
/test.txt
: No such file or directory sed: no input files
find / -maxdepth 1 -xdev -type f -print | xargs -0 grep -i "stringtofind" -l | xargs sed -i '/./d'
your find command with the missing argument is very close to working. try:
find / -maxdepth 1 -xdev -type f -exec grep -i "stringtofind" -l {} \; -exec sed -i '/./d' {} \;
you just need to add a backslash escaped semi-colon to the end of each -exec
action and add {}
to let it know where to substitute the filename.
You need to specify a file marker ( {}
) and termination (either ;
or +
) to -exec
. In addition I would suggest that you process the files with GNU parallel:
find / -maxdepth 1 -xdev -type f -exec grep -li "stringtofind" {} + |
parallel sed "'/./d'" '{}'
To handle filenames with newlines in them you need to use zero termination as suggested by others:
find / -maxdepth 1 -xdev -type f -exec grep -Zli "stringtofind" {} + |
parallel -0 sed "'/./d'" '{}'
Here's a non-parallel dependent alternative:
find / -maxdepth 1 -xdev -type f -exec grep -Zli "stringtofind" {} + |
while IFS= read -r -d $'\0' file; do
sed '/./d' "$file"
done
You have an issue with file names containing spaces. When using the -0
argument to xargs
, you should use -print0
as final argument to find
. grep
should be happy with this.
However, while this will solve the issue in the pipe between find
and grep
, it will not allow to pass the zero-separated name in the pipe from grep
to sed
. Therefore, sed
will still complain ...
Therefore, you should test with grep
within find
using -exec
, and use a single pipe to sed
, as follows. Note the use of double quotes "
around the {}
placeholder.
find / -maxdepth 1 -xdev -type f -exec grep -i "stringtofind" -q "{}" \; -print0 | xargs -0 sed '/./d'
It gives you the advantage to be able to get the list of the files that are going to be emptied by running only the first part of the command, up to but not including the |
.
find / -maxdepth 1 -xdev -type f|xargs grep -l 'string'| xargs perl -pi -e 's/.*\n//g'
上面的命令甚至会删除文件中的换行符。如果要保留新行,只删除每行中的内容,请使用以下内容:
find / -maxdepth 1 -xdev -type f|xargs grep -l 'string'| xargs perl -pi -e 's/.//g'
One way:
$ for file in $(find / -maxdepth 1 -xdev -type f -exec grep -li stringtofind '{}' \;)
> do
> > $file
> done
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.