[英]find + sed append line to beginning of file only if not there
I am writing a script that appends a line to the beginning of files in a directory. 我正在编写一个脚本,该脚本在目录中的文件开头添加一行。 The following code below does that.
下面的代码可以做到这一点。
find . -type d \( -name ThirdParty -o -name 3rdParty -o \
-name 3rd_party \) \
-prune -o -type f \( -name "*.java" -o -name "*.cs" -o \
-name "*.cpp" -o -name "*.cxx" -o \
-name "*.cc" -o -name "*.c" -o \
-name "*.h" -o -name "*.scala" -o \
-name "*.css" -o -name "*.js" \) \
-print0 |
xargs -0 sed -i '1s/^/\/*RIGHTS AND ETC ETC ETC/*'
However, I want to add this line ONLY if it is not already in the file. 但是,我只想添加此行(如果该行尚未在文件中)。 I have tried using
grep
and piping prior to using sed
as such: 在使用
sed
之前,我曾尝试使用grep
和管道:
grep -q "/*RIGHTS AND ETC ETC ETC/*" | sed -i....
but, when I run the script I get sed: no input files
. 但是,当我运行脚本时,会被
sed: no input files
。 I am simply running this script in a directory so there are no input files. 我只是在目录中运行此脚本,所以没有输入文件。 Thank you.
谢谢。
Your grep
command doesn't print anything, because you used the -q
option; 您的
grep
命令不会打印任何内容,因为您使用了-q
选项; it just sets the exit status based on whether the file matched. 它只是根据文件是否匹配来设置退出状态。
You want to print all the filenames that don't match, so you can pass those filenames to sed
. 您要打印所有不匹配的文件名,因此可以将这些文件名传递给
sed
。 You can do that with the -L
option, along with -z
to use a null terminator rather than newline (like the -print0
option in find
). 你可以做到这一点与
-L
选项,沿-z
使用空终止符,而不是换行(如-print0
在选项find
)。
You should also use -F
to treat the string as a fixed string, rather than a regular expression pattern. 您还应该使用
-F
将字符串视为固定字符串,而不是正则表达式模式。
find . -type d \( -name ThirdParty -o -name 3rdParty -o -name 3rd_party \) -prune \
-o -type f \( -name "*.java" -o -name "*.cs" -o -name "*.cpp" -o -name "*.cxx" -o -name "*.cc" -o -name "*.c" -o -name "*.h" -o -name "*.scala" -o -name "*.css" -o -name "*.js" \) -print0 |
xargs -0 grep -Lz -F "/*RIGHTS AND ETC ETC ETC/*" |
xargs -0 sed -i ...
grep
isn't needed. 不需要
grep
。 sed
can do a negative search, and make the i
nsert conditional: sed
可以做一个消极的搜索,使i
nsert条件:
... -print0 | xargs -0 sed -i '1{/^\/\*RIGHTS AND ETC ETC ETC\*\/$/!i\
/\*RIGHTS AND ETC ETC ETC\*/
}'
Notes: 笔记:
the linefeeds in the three lines of code are necessary for i
to work correctly. 三行代码中的换行符对于
i
正常工作是必需的。
it's unclear whether the *
s are literal or not, so they've been quoted like so \\*
. 尚不清楚
*
是否为文字,因此它们的引用方式为\\*
。
This might work for you (GNU sed and find): 这可能对您有用(GNU sed和查找):
(var="/*RIGHTS AND ETC ETC ETC/*" ;
find whatever \! -exec grep -qF "$var" {} \; -exec sed -i '1i\'"$var" {} \;)
Where whatever
are the initial find commands. 其中
whatever
是初始查找命令。
This will only insert the variable var
if the grep did not find var
anywhere in each entire file. 仅当grep在每个整个文件的任何地方都找不到
var
时,才插入变量var
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.