我正在编写应该处理一些文本的 shell 脚本,我得到了这样的文本:
read build { file1 file2 file3 }
check build { file2 file3 file4 }
read build { file4 file5 file6 }
我想在所有文件之前添加一些文本 - 这意味着单词,包含在“读取构建”行的括号之间,您认为实现这一目标的最佳想法是什么?结果应该如下所示:
read build { MY_ADDED_WORDfile1 MY_ADDED_WORDfile2 MY_ADDED_WORDfile3 }
check build { file2 file3 file4 }
read build { MY_ADDED_WORDfile4 MY_ADDED_WORDfile5 MY_ADDED_WORDfile6 }
我正在尝试 grep 该行,接下来将其解析为数组并将此“文件”字符串与我要添加的单词连接起来,但我认为这不是一个“智能”解决方案。感谢您的帮助。
输入文件如下所示:
set build { file1 file2 file3 file4 }
check $build
read build -new -f $build
read build -new -f { fileA fileB fileC fileD }
set build {file5 file6 file7 }
read build -old -f $build
read build -old -f { fileX fileZ fileD }
check_that_building
输出应该如下所示:
set build { file1 file2 file3 file4 }
check $build
read build -new -f $build
read build -new -f { MY_ADDED_WORDfileA MY_ADDED_WORDfileB MY_ADDED_WORDfileC MY_ADDED_WORDfileD }
set build {file5 file6 file7 }
read build -old -f $build
read build -old -f { MY_ADDED_WORDfileX MY_ADDED_WORDfileZ MY_ADDED_WORDfileD }
check_that_building
左括号前总是有一个空格,但也可能出现左括号后没有空格的情况,右括号前可以有空格,但并不总是如此。可能的情况:
read build -old -f { fileX fileZ fileD }
read build -old -f {fileX fileZ fileD }
read build -old -f { fileX fileZ fileD}
read build -old -f {fileX fileZ fileD}
答案1
sed
如果不假设至少有一个已知永远不会出现在输入中的字符,我无法立即弄清楚如何执行此操作。我假设它#
永远不会出现在输入中(或您添加的单词中)。这似乎有效:
sed '/read build/ {
s/{/{ /
: fruit
s/\({.*\) \([^}# ][^ ]*\)/\1#MY_WORD\2/
t fruit
s/#/ /g
s/{ /{/
}'
在包含read build
它的行上,首先在 后插入一个空格{
。然后它会搜索 a 之后{
且紧邻单词(可能是文件名)之前的空格。它将空格替换为#
,插入您的单词,然后返回并查找更多内容。 (fruit
是任意循环标签。) 一旦找到所有字符,它将所有#
字符转回空格,并删除它插入的空格(在 后面{
)。
#
除了关于输入中未出现的信息之外,还假设
}
是每行的最后一个非空白字符read build
,并且- 空白只是空格;没有选项卡。
在awk
:
awk '/read build/ {
in_braces=0
for (i = 1; i <= NF; i++) {
if ($i == "{") in_braces=1
else if (substr($i,1,1) == "{") {
$i = "{MYWORD" substr($i,2)
in_braces=1
}
else if ($i == "}") in_braces=0
else if (in_braces) $i = "MY_WORD" $i
}
}
{ print }'
对于每一read build
行,它循环遍历该行中的所有单词(字段)。它使用状态变量 ( in_braces
) 来跟踪它是否在 a{
和 a之间}
;如果是,它会修改每个单词以您添加的单词开头。请注意,它必须处理两种略有不同的情况:
- 如果一句话是
{
,设置标志以开始修改所有后续单词,并且 - 如果一句话开始于
{
,它实际上是形式的复合 ,所以修改{fileX
它是{
、添加的单词和fileX
文件名。并且还设置标志来修改所有后续单词。
虽然这允许制表符作为单词分隔符,但它的缺点是将空格折叠为单个空格。例如,输入
read build { file1 file2 file3 }
会产生输出
read build { MY_WORDfile1 MY_WORDfile2 MY_WORDfile3 }
此外,这假设
- the
{
位于单词的开头(即前面有空格),并且 - 要么
}
是每行的最后一个非空白字符read build
,要么是一个单独的单词(即前后都有空格)
它允许多组牙套;例如,
read build { file1 file2 file3 } text to be left alone { file4 file5 file6 }