我有一个大约1000行的文件。我希望我的文件的一部分在与我的grep语句匹配的行之后。
即
$ cat file | grep 'TERMINATE' // Its found on line 534
所以,我希望来自行535 to line 1000
的文件进行进一步处理。
我该怎么做?
答案 0 :(得分:273)
以下内容将打印匹配TERMINATE
的行,直到文件末尾:
sed -n -e '/TERMINATE/,$p'
解释: -n
禁用在{1}}上执行其脚本后打印每一行的默认行为,sed
表示脚本为-e
},sed
是一个地址(行)范围选择,意味着第一行与/TERMINATE/,$
正则表达式(如grep)匹配到文件末尾(TERMINATE
),{{1是打印当前行的打印命令。
这将从匹配$
的行后面的行打印到文件末尾:
(从匹配线到EOF之后,不包括匹配线)
p
解释: TERMINATE
是一个地址(行)范围选择,意味着第一行输入的第一行与sed -e '1,/TERMINATE/d'
正则表达式匹配,{{1删除命令是删除当前行并跳到下一行。由于1,/TERMINATE/
默认行为是打印行,它会在TERMINATE
之后打印行到输入结尾。
修改强>
如果您想要d
之前的行:
sed
如果你想在一次通过的2个不同文件中TERMINATE
之前和之后的两行:
TERMINATE
前后文件将包含终止行,因此要处理每个需要使用的行:
sed -e '/TERMINATE/,$d'
<强> EDIT2:强>
如果您不想在sed脚本中对文件名进行硬编码,则可以:
TERMINATE
但是你必须转义sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
意味着最后一行,所以shell不会尝试扩展head -n -1 before
tail -n +2 after
变量(注意我们现在在脚本周围使用双引号而不是单引号)
我忘了告诉新行在脚本中的文件名之后很重要,以便sed知道文件名结束。
修改 2016-0530
SébastienClément问道:“你如何用变量替换硬编码的before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
?”
您可以为匹配的文本创建一个变量,然后以与上一个示例相同的方式执行此操作:
$
将匹配文本的变量用于前面的示例:
$w
TERMINATE
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
在这些情况下,用变量替换文本的重点是:
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
[## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
]中的变量(## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
)不会“展开”,但$variablename
[single quotes
]中的变量会出现。因此,如果它们包含要用变量替换的文本,则必须将所有'
更改为double quotes
。 "
范围也包含single quotes
,后面跟着一个字母,如:double quotes
,sed
,$
。它们看起来也像要扩展的变量,因此您必须使用反斜杠[$p
]转义那些$d
个字符,例如:$w
,$
,{{1} }。答案 1 :(得分:60)
作为简单的近似,您可以使用
grep -A100000 TERMINATE file
对TERMINATE
进行grep,并在该行后输出最多100000行。
来自手册页
-A NUM, --after-context=NUM
在匹配行后打印NUM行尾随上下文。 放置一个包含组分隔符( - )的行 连续的比赛组。使用-o或--only匹配 选项,这没有效果,并给出警告。
答案 2 :(得分:26)
这里使用的工具是awk:
cat file | awk 'BEGIN{ found=0} /TERMINATE/{found=1} {if (found) print }'
这是如何运作的:
如果您在非常大的文件上使用它们,其他解决方案可能会占用大量内存。
答案 3 :(得分:7)
使用bash参数扩展,如下所示:
content=$(cat file)
echo "${content#*TERMINATE}"
答案 4 :(得分:7)
如果我正确理解了您的问题,您确实需要 TERMINATE
之后的行,而不包括TERMINATE
行。 awk
可以通过简单的方式完成此操作:
awk '{if(found) print} /TERMINATE/{found=1}' your_file
说明:
if(found) print
)将不会打印任何内容。这将打印 TERMINATE
- 行后的所有行。
<强>概括强>
示例:
$ cat ex_file.txt
not this line
second line
START
A good line to include
And this line
Yep
END
Nope more
...
never ever
$ awk '/END/{found=0} {if(found) print} /START/{found=1}' ex_file.txt
A good line to include
And this line
Yep
$
说明:
found
,则打印当前行。found=1
以便打印以下行。请注意,此检查在 实际打印后完成,以从结果中排除开始 -line。注意:
BEGIN{found=0}
。答案 5 :(得分:4)
grep -A 10000000'TERMINATE'文件
答案 6 :(得分:3)
如果出于任何原因,您希望避免使用sed,则以下内容将打印匹配TERMINATE
的行,直到文件末尾:
tail -n "+$(grep -n 'TERMINATE' file | head -n 1 | cut -d ":" -f 1)" file
以下内容将从匹配TERMINATE
的以下行打印到文件末尾:
tail -n "+$(($(grep -n 'TERMINATE' file | head -n 1 | cut -d ":" -f 1)+1))" file
在一个进程中执行sed可以执行的操作需要2个进程,如果文件在执行grep和tail之间发生更改,则结果可能会不连贯,因此我建议使用sed。此外,如果文件dones不包含TERMINATE
,则第一个命令失败。
答案 7 :(得分:2)
使用sed
或awk
:
sed -n '/TERMINATE/,$p' file
这将在您的文件中查找TERMINATE
并从该行打印到文件末尾。
awk '/TERMINATE/,0' file
这与sed
完全相同。
如果您知道要从中开始打印的行号,可以将其与NR
一起指定(记录数,最终表示行号):
awk 'NR>=535' file
$ seq 10 > a #generate a file with one number per line, from 1 to 10
$ sed -n '/7/,$p' a
7
8
9
10
$ awk '/7/,0' a
7
8
9
10
$ awk 'NR>=7' a
7
8
9
10
答案 8 :(得分:0)
jfgagne提供的优秀clang
答案的替代方案,并且不包括匹配的行:
sed
(https://stackoverflow.com/a/18166628)awk '/TERMINATE/ {y=1;next} y'
(https://stackoverflow.com/a/23984891)awk '/TERMINATE/ ? c++ : c'
(https://stackoverflow.com/a/18167194)答案 9 :(得分:0)
这可能是一种做法。如果您知道文件的哪一行,那么您的grep单词和文件中有多少行:
grep -A466'TERMINATE'文件
答案 10 :(得分:-1)
sed是一个更好的工具: sed -n'/ re /,$ p'文件
其中re是regexp。
另一种选择是grep的--after-context标志。你需要传入一个数字来结束,使用文件上的wc应该给出正确的值来停止。将此与-n和您的匹配表达式结合使用。
答案 11 :(得分:-2)
这些将打印从最后找到的行“TERMINATE”到文件结尾的所有行:
transition