bash 在文件中第一次出现特定字符串之前删除所有行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35965783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Delete all lines before first occurrence of specific string in file
提问by mtveezy
Basically I have a file like:
基本上我有一个文件,如:
junk
morejunk
somestring
bats
car
somestring
bats
car
somestring
bats
car
and I want to remove all of the junk
before the first occurrence of somestring
so the file looks like
我想junk
在第一次出现之前删除所有somestring
的文件,所以文件看起来像
somestring
bats
car
somestring
bats
car
somestring
bats
car
I followed the advice from this questionto use sed -i '0,/somestring/,d' file.txt
but it deletes the line with the first occurrence of somestring
, when I want to keep that line as the first line.
我按照this question的建议使用,但当我想将该行保留为第一行时,sed -i '0,/somestring/,d' file.txt
它会删除第一次出现的somestring
行。
回答by l'L'l
With sed
you could use:
有了sed
你可以使用:
sed -i '/somestring/,$!d' file
Explanation of replace expressions:
替换表达式的解释:
,
matches lines starting from where the first address matches, and continues until the second match (inclusively).
$
matches the last line of the last file of input, or the last line of each file when the -i or -s options are specified.
!
If the character follows an address range, then only lines which do not match the address range will be selected.
d
Delete the pattern space; immediately start next cycle.
,
匹配从第一个地址匹配的位置开始的行,并一直持续到第二个匹配(包括)。
$
匹配输入的最后一个文件的最后一行,或指定 -i 或 -s 选项时每个文件的最后一行。
!
如果字符跟在地址范围之后,则只会选择与地址范围不匹配的行。
d
删除模式空间;立即开始下一个循环。
Result:
结果:
$ sed -i '/somestring/,$!d' file
somestring
bats
car
somestring
bats
car
somestring
bats
car
回答by Benjamin W.
$ sed -n '/somestring/,$p' infile
somestring
bats
car
somestring
bats
car
somestring
bats
car
The command suppresses printing with -n
, and then for the address range /somestring/,$
, i.e., from somestring
to the last line, executes the p
command to print the line.
该命令禁止打印-n
,然后对于地址范围/somestring/,$
,即从somestring
到最后一行,执行该p
命令以打印该行。
回答by Tom Fenech
Here's a way you can do it using awk:
这是您可以使用 awk 执行此操作的一种方法:
awk '/somestring/ { f = 1 } f' file
When the pattern matches, set f
to true. When f
becomes true, print each line.
当模式匹配时,设置f
为 true。当f
变为真时,打印每一行。
Another option, slightly more cryptic:
另一种选择,稍微有点神秘:
awk 'f += /somestring/' file
f
is increased by either 1
when the pattern matches or 0
when it doesn't. Once a line has matched the pattern, the expression becomes true, so each line is printed.
f
1
当模式匹配或0
不匹配时增加。一旦一行与模式匹配,表达式就变为真,因此打印每一行。
回答by karakfa
another idiomatic awk
solution (and fewest keystrokes) is
另一个惯用的awk
解决方案(和最少的击键)是
$ awk '/somestring/,0' file
somestring
bats
car
somestring
bats
car
somestring
bats
car
回答by Todd A. Jacobs
Concatenate with Echo and GNU Sed
与 Echo 和 GNU Sed 连接
You had most of the solution with GNU sed, which allows you to use both line numbers and regular expressions in range patterns. All you really need to do to get the behavior you want is to prepend the string you're using as your end-pattern to the resulting output.
您拥有 GNU sed 的大部分解决方案,它允许您在范围模式中使用行号和正则表达式。要获得所需的行为,您真正需要做的就是将用作最终模式的字符串添加到结果输出中。
For example:
例如:
$ str='somestring'; echo -e "${str}\n$(sed "0,/${str}/d" /tmp/corpus)"
somestring
bats
car
somestring
bats
car
somestring
bats
car
Basically, you assign the pattern to str, which you then reuse in both the echo statement and the sed expression. If you run into quoting problems related to variable interpolation, just replace the strvariable with fixed strings in both your echo and sed commands. However, works as-is with the posted corpus.
基本上,您将模式分配给str,然后在 echo 语句和 sed 表达式中重用它。如果遇到与变量插值相关的引用问题,只需在 echo 和 sed 命令中将str变量替换为固定字符串即可。但是,对已发布的语料库按原样工作。