我有一个以一些“include”语句开头的文件,如下所示:
include foo.xyz
include bar.xyz
do c
do d
假设该文件foo.xyz
包含do a
且该文件bar.xyz
包含do b
.如何编写一个脚本include file.xyz
来用 的上下文替换每个语句file.xyz
?我想最终得到以下输出:
do a
do b
do c
do d
我尝试了“使用 sed 将字符串替换为文件内容“但是文件名是硬编码的。我希望根据参数动态生成文件名include
。
答案1
这是使用 awk 的简单递归版本。您必须在 PATH 中创建一个脚本
#!/bin/bash
awk '
$1=="include" && NF>=2 {
system("'$0' " $2)
next
}
{print}' "$@"
它假设文件名中没有特殊字符(包括空格)。 awk 检查第一个单词是否包含,然后调用脚本来处理作为第二个单词给出的文件。打印其他行。注意$0
这里是外部awk 的单引号,shell 也是如此$0
,即脚本名称。
答案2
grep -n '^include ' yourfile |
sed -e 's/:[^ ]* /{ r /' \
-e 'G;s/.$/&b&}/' |
sed -nf - -ep yourfile
那应该有效。grep
找到那些包括行号,第一个sed
将其输出修改为特定于行号的[num]{r fname\nb\n}
命令,第二个sed
p
打印不是其第一个脚本之一的每一行。
{ for x in a b
do echo "do $x">"file$x.xyz"
echo "include file$x.xyz"
done; printf "do %s\n" c d
} >yourfile
cat yourfile
include filea.xyz
include fileb.xyz
do c
do d
这只会生成您的样本并显示你的档案。
这有效:
grep -n '^include ' yourfile |
sed -e 's/:[^ ]* /{ r /' \
-e 'G;s/.$/&b&}/' |
sed -nf - -ep yourfile
do a
do b
do c
do d
当然, eadr
文件可以是任意大小,并且不限于单行。虽然文件名本身仅限于一行,但在其他方面或多或少不受限制(取决于你的sed
- 一些较旧的seds
有任意名称长度限制,但今天使用的大多数没有)。
答案3
cat $(grep '^include' file.txt | cut -d" " -f2); grep -v '^include' file.txt
第一个命令将以ingrep
开头的行,文件名部分,然后是它。include
file.txt
cut
cat
下一个命令将打印除以include
in开头的行之外的所有行file.txt