我需要在csh中编写一个shell脚本来search和删除与上一行中的注释匹配的行,如果有的话。 例如,如果我的文件有以下几行
Shell脚本 #这是一个testing 模式1 格式1 模式2 FORMAT2 #format3 pattern3
如果search模式是“模式”,输出应该如下
Shell脚本 格式1 FORMAT2
更准确地说,如果以“#”开头,那么具有该模式和前一行的行应该被删除
谢谢您的帮助
也许更好的方式来写这逻辑上,但我认为这可能会做到这一点:
#!/usr/bin/perl use strict; use warnings; my $previous_line = ''; while(<>) { if ( /pattern/ ) { if ( (! ($previous_line =~ /^#/)) && (! ($previous_line =~ /pattern/))) { print $previous_line; } } elsif (! ($previous_line =~ /pattern/)) { print $previous_line; } $previous_line = $_; } print $previous_line if not ($previous_line =~ /pattern/);
基本上,循环是前一行的后面一行。 它说,如果出现以下情况,可以打印上一行 :
您可以将代码保存在一个文件中并像下面这样使用它: perl thefile.pl textfile_you_want_to_filter
首先,任何人都不应该使用csh来完成任何事情 – 它已经过时了,而且还没有(不是“不”)驱动。 其次,我怀疑这是完成任务。 第三, awk , sed甚至Perl将成为更好的工具。
awk '/^#/ {printf line; line=$0"\n"; next} /pattern/ {line=""} ! /pattern/ {printf line; print; line=""}'
编辑:修正脚本正确处理注释行
这是Perl中的一个单线程解决scheme(不在C shell中)。 你可以在中间修改/pattern/正则expression式。
perl -ne 'if(/^#/){$c=$_}elsif(!/pattern/){print$c,$_;$c=""}else{$c=""}' <file.in
这是一个sed版本。 某些版本的sed可能需要将这些部分分成多个-e子句。
sed '$b;N;/^#.*\npattern.*$/ ! {P;D}; :c; $d; s/.*\n//;N;/^#.*\npattern.*$/ {bc}; /^pattern/d; D' patterns
这是一个脚本文件版本的一行评论:
#!/bin/sed -f # Search for a combination of a comment followed by a pattern # until that, print what you find. $b N /^#.*\npattern.*$/ ! { P D } :c # Got a comment and a pattern combination in pattern space. # At the end of the file we simply exit $d # Else, we keep reading lines with `N' until we # find a different one s/.*\n// N /^#.*\npattern.*$/ { bc } # Remove standalone lines that have "pattern" /^pattern/d # Remove the last instance of the combination # and go back to the top D
这是基于info sed节4.16“删除所有重复的行”(uniq -u)中的脚本。
它必须是shell脚本?
:g/<pattern>/d :g/^#/d 如果必须脚本化,可以使用sed有效地复制
编辑:
1.create文件.scripts:
/pattern/d /^#/d
2. sed -f .sedscript <inputfile> > <outputfile>
这不符合删除上一行的要求,但您的示例似乎并不需要该function。