使用Bash向源文件添加标头



我有一个脚本,它添加了一个字符串C++源文件:

for f in $(find . -name '*.h' -or -name '*.cpp');
do sed -i '1s/^/<added text> /' $f;
done;

如何添加多行变量值?

尝试过,但没有成功:

h=$'//Copyright 2021 My Corporationn//Authors: me and othersn'

变量CCD_ 1变为单行。

使用ed而不是sed来编辑文件。

如果使用bash:,也不需要使用find来定位文件

#!/usr/bin/env bash
h=$'//Copyright 2021 My Corporationn//Authors: me and othersn'
# Turn on recursive globbing and extended globbing and have patterns that
# fail to match expand to an empty string
shopt -s globstar extglob nullglob
for f in **/*.@(h|cpp); do
# Add the contents of the variable h at the beginning of the file
# Note: no lines in $h should be just a period as that signals end of
# text input mode.
ed -s "$f" <<EOF
1i
$h
.
w
EOF
done

如果由于某种原因必须使用sed,您还希望使用其i命令,而不是s(人们往往会忘记sed甚至还有其他命令),它会插入以下文本行,直到末尾没有反斜杠的文本行标记最后一行输入。当然,需要一些h0参数扩展来将变量转换为适当的形式:

#!/usr/bin/env bash
h=$'//Copyright 2021 My Corporationn//Authors: me and othersn'
# Add a newline at the very beginning, and a backlash at the end
# of each line
h=$'n'"${h//$'n'/$'\n'}"
# Or just format the original string appropriately at the start
# h=$'n//Copyright 2021 My Corporation\n//Authors: me and others\n'
shopt -s globstar extglob nullglob
for f in **/*.@(h|cpp); do
sed -i -e "1i\$h" "$f"
done
# If using GNU sed, you can avoid the loop:
# sed -si -e "1i\$h" **/*.@(h|cpp)

sed在处理嵌入式(单字符)n时可能有点不稳定;我们可以通过几种方式来解决这个问题。。。

样本输入文件:

$ cat xx
1
2
3

根据${h}变量的定义,有几个sed的想法:

1)用文字/单字符n:定义的${h}

$ h=$'//Copyright 2021 My Corporationn//Authors: me and othersn'
$ sed "1 s|^|${h//$'n'/\n}|" xx

其中:

  • 1 s|^|-第1行,将行的开头替换为
  • ${h//$'n'/\n}-将所有单字符n更改为3字符\n(转义的+n)
  • 注意:因为/字符显示在数据中,所以sed命令需要不同的分隔符,因此|

2)${h}定义为2个字符的+n:

$ h='//Copyright 2021 My Corporationn//Authors: me and othersn'
$ sed "1 s|^|${h///\}|" xx*

其中:

  • 1 s|^|-第1行,将行的开头替换为
  • ${h///\}-转义所有(注意:这可能会导致出现无法解释为控制字符的问题)
  • 注意:因为/字符显示在数据中,所以sed命令需要不同的分隔符,因此|

这两者都会生成:

//Copyright 2021 My Corporation
//Authors: me and others
1
2
3

一旦OP对结果满意,就可以添加-i标志来执行就地更新。

使用sed是过度使用sed语法的限制。

改为使用cat

#!/usr/bin/env bash
# Some helpful settings to avoid editing the core code
corporation='Example INC'
authors=(
'me'
'someone'
'someone-else'
)
# Capture the year (require bash 4.2+)
# If older bash, use year="$(date '+%Y')"
printf -v year '%(%Y)T'
# Be sure tmp_file variable does not exist (may have been exported)
unset tmp_file
# Prepare EXIT trap to clean-up temporary file
trap 'rm -f -- "$tmp_file"' EXIT
# Safely create a temporary file to hold changes
tmp_file="$(mktemp)"
# Find .h or .cpp files and make it a null delimited records stream
find . ( -name '*.h' -or -name '*.cpp' ) -print0 |
# Iterate the null delimited file names
while read -r -d '' cpp_file; do
# Skip files already containing the copyright header
tail -n2 "$cpp_file" | grep -qF ' * Copyright' && continue
# If successfully merging here-document header with file
# into the temporary file
if cat - "$cpp_file" >"$tmp_file" <<EOF
/*
* Copyright ${year} ${corporation}
* Authors: ${authors[*]}
*
*/
EOF
# then copy the temporary file over
then cp "$tmp_file" "$cpp_file"
fi
done

最新更新