我想在Bash中忽略所有出现在匹配行之前的行(也忽略匹配行)。输入的示例可能如下:
R1-01.sql
R1-02.sql
R1-03.sql
R1-04.sql
R2-01.sql
R2-02.sql
R2-03.sql
如果我在已排序的输入中找到匹配的 R2-01.sql
,我希望得到:
R2-02.sql
R2-03.sql
我想在Bash中忽略所有出现在匹配行之前的行(也忽略匹配行)。输入的示例可能如下:
R1-01.sql
R1-02.sql
R1-03.sql
R1-04.sql
R2-01.sql
R2-02.sql
R2-03.sql
如果我在已排序的输入中找到匹配的 R2-01.sql
,我希望得到:
R2-02.sql
R2-03.sql
有很多种方法。例如:假设你的输入在list.txt文件中。
PATTERN="R2-01.sql"
sed "0,/$PATTERN/d" <list.txt
因为0,/pattern/
只在GNU sed上有效(例如在OS X上无效),所以这里提供了一个被篡改的解决方案。 ;)
PATTERN="R2-01.sql"
(echo "dummy-line-to-the-start" ; cat - ) < list.txt | sed "1,/$PATTERN/d"
这将在开头添加一行虚拟行,因此真正的模式必须在第1行或更高位置,所以1,/pattern/
将起作用-删除从第1行(虚拟行)到模式的所有内容。
或者您可以打印模式后的行并删除第一行,例如:
sed -n '/pattern/,$p' < list.txt | sed '1d'
使用awk,例如:
awk '/pattern/,0{if (!/pattern/)print}' < list.txt
或者,我最喜欢的方式是使用下一个Perl命令:
perl -ne 'print unless 1../pattern/' < list.txt
当模式在第一行时,删除第一行...
另一种解决方案是反向-删除-反向。
tail -r < list.txt | sed '/pattern/,$d' | tail -r
如果你有tac
命令,使用它替代tail -r
。有趣的是/pattern/,$d'在最后一行起作用,但是
1,/pattern/d`在第一行却不起作用。
如何在bash中忽略匹配前的所有行?
问题标题和您的示例不完全对应。
使用sed
,打印从"R2-01.sql"开始的所有行:
sed -n '/R2-01.sql/,$p' input_file.txt
问题所在:
-n
抑制将模式空间打印到标准输出(stdout)/
开始和结束匹配的模式(正则表达式),
分隔起始范围和结束范围$
定位到输入中的最后一行p
在该范围内回显模式空间到stdoutinput_file.txt
是输入文件在sed
中打印所有在"R2-01.sql"之后的行:
sed '1,/R2-01.sql/d' input_file.txt
1
表示输入的第一行,
分离起始范围和结束范围/
开始和结束匹配模式(正则表达式)$
表示输入中的最后一行d
删除该范围内的模式空间input_file.txt
是输入文件R2-01.sql
,而不是 $PATTERN
。 - user5359531$PATTERN
,但是这可以相对容易地进行调整。 - johnsyweb$ grep -A99999 $match $file
$ grep -A$(wc -l $file) $match $file
当然,那时你可能最好使用sed
解决方案,因为它们不需要读取文件两次。
如果你不想要匹配的行本身,你可以将此命令简单地导入tail -n+1
来跳过输出的第一行。
sed
解决方案的替代方案,如果您不想这样做,可以不使用它。 - dimo414grep
命令,配合 wc -l
。 - user5359531awk -v pattern=R2-01.sql '
print_it {print}
$0 ~ pattern {print_it = 1}
'
perl -ne 'if ($f){print} elsif (/R2-01\.sql/){$f++}' sql
要将正则表达式作为参数传递,请使用-s
启用简单的参数解析器。
perl -sne 'if ($f){print} elsif (/$r/){$f++}' -- -r=R2-01\\.sql file
你可以这样做,但我认为jomo666的答案更好。
sed -nr '/R2-01.sql/,${/R2-01/d;p}' <<END
R1-01.sql
R1-02.sql
R1-03.sql
R1-04.sql
R2-01.sql
R2-02.sql
R2-03.sql
END
grep
实现,通过打印足够多的上下文来跟随$match
。该示例将输出第一个匹配行,后跟999,999行的“上下文”。grep -A999999 $match $file
$match
以连字符开头),您应该使用-e
来强制使用$match
作为表达式。grep -A999999 -e '$match' $file