2016-11-20 95 views
0

说我有一个这样的文件:循环sed脚本内不会终止

... 
{ 
    ... 
    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) 
    ... 
} 

我想要做的首先是,使用SED,加载含图案的 “--foo” 到所有行模式空间并打印出来只是paranthesis内的部分,所以我用命令:

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

这不正是我想要的东西,所以我得到作为输出:

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

接下来我想合并所有的行到一个空白的内容。我可以解决这个使用命令替换:

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

这给了我:

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

接下来,我要插入一些betwenn的参数,例如1,所以最终的结果应该是这样的:

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

我几乎可以解决这个问题。我使用的命令:

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' 

,但我得到两个小问题。首先,我跳回到我开始前标记输出被管道输送到最后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 

等。所以我的第一个问题是,我怎样才能避免每次输出到最后的sed语句中。我可以使用不同的sed选项/标志来实现这一点吗?

第二个问题是,命令没有终止。迭代与

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

结束。如可以看到的,第二最后一个项目后面的“1”不追加并且另外整个命令不会终止。我必须使用Ctrl-C来终止它。

+1

符号'''echo'sed ... file' | sed ...'''很糟糕。你应该使用'''sed ... file | sed ...'''。您按顺序运行3个sed命令;应该简化为一个,或者应该使用'awk'(或Perl或Python)来代替。 –

+0

欢迎使用堆栈溢出。 请注意,在这里说'谢谢'的首选方式是通过 提高投票的好问题和有用的答案(一旦你有足够的声誉这样做),并接受任何 问题最有用的答案,你问(这也给你一个小小的提升,以你的声望 )。 请参阅[关于]页面,以及[如何在此处提问 ?]和 [当有人回答我的 问题时,我该怎么办? ?](http://stackoverflow.com/help/someone-answers) –

回答

1

使用稍作修改你的第一个命令:

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

已经提取的名字,随后将其追加数字。 tr命令将换行符转换为空格。你可以在sed;它会很烦琐,就是这样。


其实,这是不是所有的更加繁琐,但它需要寻找的过程中以不同的方式。具体而言,需要匹配的模式保存在货舱空间,然后处理它们在输入的末尾:

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

}字符前的分号是必要的BSD(MacOS的)sed,但不与GNU sed。第一个-e选项会查找与您的模式相匹配的行,然后将替代命令应用于该行以仅保留--name部分加上数字1,然后将该信息附加到换行符后的保留空间。第二个-e选项适用于最后一行。它交换模式并保留空格,然后用空格替换每一个换行符并打印结果,包括尾部换行符,脚本用tr代替空白。

输出(注意前导空白):

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

如果你不想前导空白,打印(在p前添加s/^ //;)之前将其删除。

+0

谢谢,这工作。所以,我假设我以复杂的方式尝试了它;-)。至少我学到了... – FloHe

+0

@FloHe:看到更新 - 我的第一个解决方案使用两个命令,其中一个就足够了。 –