我有以下代码行,用于将我的项目中的个人日期变量更新为今天的当前日期。这条线在Ubuntu的终端上工作,但Mac终端似乎远远落后。不幸的是,我从某个网站复制了这个片段,所以我不确定它是如何工作的。建议?
grep -ilr --exclude=revar.sh --exclude=README.md "[DATE]" * |
grep -v .git | xargs -i@ sed -i "s/\[DATE\]/${today}/g" @
我有以下代码行,用于将我的项目中的个人日期变量更新为今天的当前日期。这条线在Ubuntu的终端上工作,但Mac终端似乎远远落后。不幸的是,我从某个网站复制了这个片段,所以我不确定它是如何工作的。建议?
grep -ilr --exclude=revar.sh --exclude=README.md "[DATE]" * |
grep -v .git | xargs -i@ sed -i "s/\[DATE\]/${today}/g" @
Answers:
生成文件名列表:
grep -ilr --exclude=revar.sh --exclude=README.md "[DATE]" *
以递归方式(-r)搜索文件,并列出(-l)文件内容不区分大小写的那些名称(-i)正则表达式“[DATE]”(这意味着该文件包含任何一个8个字符“AaDdEeTt”);排除名称revar.sh和README.md,和
从列表中删除包含字符后跟'git'的所有文件名(因此将删除文件名'agitator'):
grep -v .git
一次处理一个文件,将特定的“sed”脚本应用于该文件。在现代符号中(POSIX - 和MacOS X,以及Linux,AIX,HP-UX,Solaris等):
xargs -I@ sed -i "s/\[DATE\]/${today}/g" @
'sed'的'-i'选项意味着在处理后覆盖输入文件。这是在POSIX标准中未指定的'sed'的GNU和BSD扩展。
这个剧本可以在很多层面受到批评。
因此,两种选择中的一种是有道理的。
或者:
grep -ilr --exclude=revar.sh --exclude=README.md "\[DATE\]" * |
grep -v '\.git/' |
xargs sed -i "s/\[[Dd][Aa][Tt][Ee]\]/${today}/g"
要么:
grep -lr --exclude=revar.sh --exclude=README.md "\[DATE\]" * |
grep -v '\.git/' |
xargs sed -i "s/\[DATE\]/${today}/g"
正如Donal Fellows所指出的那样,在这种情况下,没有必要使用'-i'或'-I'选项来'xargs'。
这让我感到疑惑它是如何有用的。在第一天,所有出现的'[DATE]'都映射到'2010-04-17';第二天会发生什么?在提交到git存储库之前,如何取消映射日期?
不过,至少你现在知道它的作用以及它是如何做到的。
BSD xargs
不具有 -i
,无论如何,这个选项在GNU xargs中被弃用了(这个指南是什么时候写的?1995年?)。使用 -I
代替。
-I
,例如 redis-cli keys 'foo*' | xargs -I@ echo @
该 -i
选项 xargs
当执行替换的地方在字符串的末尾时,永远不需要;无论如何,这就是放置文件名的地方。和BSD xargs
(这是OSX提供的)也不支持该选项。试试这个:
grep -ilr --exclude=revar.sh --exclude=README.md "[DATE]" * |
grep -v .git | xargs sed -i "s/\[DATE\]/${today}/g"
至于要在Mac OS X上进行sed的-i标志以便就地编辑文件,你必须添加一个空字符串作为参数:
sed -i "" 's/regex/replace/g' file
sed -i "" 's/regex/'"${var}"'/g' file # create sed expression using string concatenation
sed -i ".BAK" 's/regex/replace/g' file
将创建一个名为“file.BAK”的备份文件。
使用Bash参数扩展您几乎可以自动避免sed格式问题:
# some basic Bash parameter expansion examples to play with
var='ddd/abc/ddd'
var="$(date)"
var=$'\\\n'
echo abc | sed 's/b/'"${var}"'/g'
echo abc | sed 's/b/'"${var//\//\\/}"'/g'