简体   繁体   English

sed脚本中的循环不会终止

[英]loop inside sed script doesn't terminate

Say I have a file like this: 说我有一个像这样的文件:

...
{
     ...
     cout<< "---at time:\t\t"<< sc_core::sc_time_stamp()<<"\n\n" << endl;
     ...
     cout<< "---at time:\t\t"<< sc_core::sc_time_stamp()<<"\n\n" << endl;
     ...
}
...
{
     ...
     if(strcmp(argv[1], "--io_freq1_Mhz") != 0)
     if(strcmp(argv[2], "--io_freq2_Mhz") != 0)
     ...
     if(strcmp(argv[11], "--bytes_per_word") != 0)
     ...
     if(strcmp(argv[23], "--mem_size_bytes") != 0)
     ...
}

What I want do first is, using sed, loading all lines containing the pattern "--foo" into pattern space and printing out just the part inside the paranthesis, so I use the command: 我首先要使用的是sed,将包含模式“ --foo”的所有行加载到模式空间中,然后仅打印出括号内的部分,因此我使用以下命令:

sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1/p' file

which does exactly what I want, so I get as an output: 正是我想要的,所以我得到了一个输出:

--io_freq1_Mhz
--io_freq2_Mhz
...
--bytes_per_word
...
--mem_size_bytes

Next I want to merge all the lines into one and separating the content by a blank. 接下来,我想将所有行合并为一个,并用空格分隔内容。 I can solve this using command substitution: 我可以使用命令替换解决此问题:

echo `sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1/p' file`

This gives me: 这给了我:

--io_freq1_Mhz --io_freq2_Mhz --... --bytes_per_word --... --mem_size_bytes

Next I want to insert a number betwenn the parameters, for example 1, so the final result should look like: 接下来,我想在参数之间插入一个数字,例如1,因此最终结果应如下所示:

--io_freq1_Mhz 1 --io_freq2_Mhz 1 --... 1 --bytes_per_word 1 --... 1 --mem_size_bytes 1

I can almost solve this. 我几乎可以解决这个问题。 I'm using the command: 我正在使用以下命令:

echo `sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1/p' file` | sed -n -e ':start { s/\(--[^\ ]*\) -/\1 1 -/p; b start }' | sed -n -e 's/\(--.*[^\ ]\)/\1 1/p'

but I get two minor problems. 但是我遇到两个小问题。 First of all, before I'm jumping back to my start mark the output gets piped into the last sed statement, that means I get as an output: 首先,在我回到开始标记之前,将输出通过管道传递到最后的sed语句中,这意味着我将获得以下输出:

--io_freq1_Mhz 1 --io_freq2_Mhz --... --bytes_per_word --... --mem_size_bytes 1
--io_freq1_Mhz 1 --io_freq2_Mhz 1 --... --bytes_per_word --... --mem_size_bytes 1

and so on. 等等。 So my first question is, how I can avoid piping the output every time into my last sed statement. 所以我的第一个问题是,如何避免每次都将输出传递到最后一个sed语句中。 Can I achieve this using different sed options/flags? 我可以使用不同的sed选项/标志来实现吗?

The second problem is, that the command doesn't terminate. 第二个问题是命令不会终止。 The iteration ends with 迭代以

--io_freq1_Mhz 1 --io_freq2_Mhz 1 --... --bytes_per_word 1 --... --third_last_item 1 --second_last_item mem_size_bytes 1

As can be seen, behind the second last item a '1' isn't appended and additionally the whole command doesn't terminate. 可以看出,在倒数第二个项目后面没有附加“ 1”,并且整个命令也没有终止。 I have to terminate it using Ctrl-C. 我必须使用Ctrl-C终止它。

Use a minor modification of your first command: 对第一个命令进行较小的修改:

sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1 1/p' file | tr '\n' ' '

Having extracted the name, append the digit after it. 提取名称后,在其后附加数字。 The tr command converts newlines into blanks. tr命令将换行符转换为空格。 You could do it all in sed ; 您可以在sed完成所有操作; it would be fiddly, that's all. 这很奇怪,仅此而已。


Actually, it isn't all that much more fiddly, but it requires a different way of looking at the process. 实际上,这并不那么有趣,但是它需要以不同的方式看待流程。 Specifically, you need to save the matching patterns in the hold space, and then process them all at the end of the input: 具体来说,您需要将匹配的模式保存在保留空间中,然后在输入末尾全部处理它们:

sed -n \
    -e '/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/{ s//\1 1/; H; }' \
    -e '$ { x; s/\n/ /g; p; }' file 

The semicolons before the } characters are necessary with BSD (macOS) sed , but not with GNU sed . }字符前的分号对于BSD(macOS) sed是必需的,而对于GNU sed不是必需的。 The first -e option finds lines that match your pattern, and then applies a substitute command to the line to retain just the --name part plus a digit 1, and then appends that information to the hold space after a newline. 第一个-e选项查找与您的模式匹配的行,然后向该行应用替换命令以仅保留--name部分和数字1,然后将该信息追加到换行符之后的保留空间中。 The second -e option works on the last line. 第二个-e选项在最后一行起作用。 It exchanges the pattern and hold spaces, then replaces every newline with a blank and prints the result, including a trailing newline which the script with tr replaces with a blank. 它交换模式并保留空格,然后用空格替换每个换行符并打印结果,包括结尾的换行符,用tr的脚本将其替换为空格。

Output (note the leading blank): 输出(注意前导空白):

 --io_freq1_Mhz 1 --io_freq2_Mhz 1 --bytes_per_word 1 --mem_size_bytes 1

If you don't want the leading blank, remove it before printing (add s/^ //; before the p ). 如果您不希望前导空白,请在打印之前将其删除(在p之前添加s/^ //; )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM