使用bash shell脚本在2个字符串之间提取字符串
我看过类似这样的问题,但在这种情况下似乎没有任何解决方案可行。我有一个文本文件,它看起来像这样使用bash shell脚本在2个字符串之间提取字符串
START-OF-FILE
RUNDATE=20140910
FIRMNAME=dl
FILETYPE=pc
REPLYFILENAME=TEST
DERIVED=yes
PROGRAMFLAG=oneshot
SECID=ISIN
SECMASTER=yes
PROGRAMNAME=getdata
START-OF-FIELDS
ISSUER
START-OF-DATA
US345370CN85|0|4|FORD MOTOR COMPANY|FORD MOTOR COMPANY| | |
US31679BAC46|0|4|FIFTH STREET FINANCE COR|FIFTH STREET FINANCE COR| | |
END-OF-DATA
END-OF-FILE
我试图写一个bash shell脚本只提取“START-OF-DATA”和“END-OF-DATA”排除两者之间的文本这些。所以输出我要找的应该是这样的
US345370CN85|0|4|FORD MOTOR COMPANY|FORD MOTOR COMPANY| | |
US31679BAC46|0|4|FIFTH STREET FINANCE COR|FIFTH STREET FINANCE COR| | |
到目前为止,我写的代码看起来像这样
while read line
do
name=$line
echo $name | sed -e 's/START-OF-DATA\(.*\)END-OF-DATA/\1/'
done < $1
和庆典像
./script.sh file.txt
那里运行它script.sh是我保存的shell脚本,而file.txt是它读取的文本文件。目前它只读取和回显整个文件。我猜我的语法有点傻。任何在正确的方向指针将不胜感激。 感谢
使用awk
你可以这样做:
awk '/START-OF-DATA/{p=1;next} /END-OF-DATA/{p=0;exit} p' file
US345370CN85|0|4|FORD MOTOR COMPANY|FORD MOTOR COMPANY| | |
US31679BAC46|0|4|FIFTH STREET FINANCE COR|FIFTH STREET FINANCE COR| | |
或者使用sed
:
sed -n '/START-OF-DATA/,/END-OF-DATA/{/START-OF-DATA\|END-OF-DATA/!p;}' file
US345370CN85|0|4|FORD MOTOR COMPANY|FORD MOTOR COMPANY| | |
US31679BAC46|0|4|FIFTH STREET FINANCE COR|FIFTH STREET FINANCE COR| | |
为了使您的解决方案工作,你可以做一个标记,当你点击“START-OF- DATA“读取”True“(或类似),然后在您点击”数据结束“时结束。使用此标记可以指示回显打印标记为“真”(当您位于相关文本块内时)。
...或者你可以使用SED:
sed -n '/START-OF-DATA/,/END-OF-DATA/ { //!p }' file.txt
感谢您的回复bryn。您的解决方案完美运作由于他的回复速度更快,我不得不赞同@anubhava。不过谢谢。现在脚本工作正常。问候 – tasslebear 2014-09-11 11:52:42
您好bryn。你的[tag:sed]命令行比[anubhava的一个]更好(http://stackoverflow.com/a/25786380/938111)。但对我来说有点神秘:我想知道'{// p}'中的'//'意味着什么。请给出一些解释或链接到网站解释这一点。干杯;-) – olibre 2014-09-12 08:49:56
我想补充Perlish的grep
方式,如前所述here:
grep -Pzo "(?s)START-OF-DATA.*END-OF-DATA" "$1"
这仍然包括START-OF-DATA
和END-OF-DATA
标记。要摆脱他们,该模式有可能成为一个有点不太可读:
grep -Pzo "(?s)(?<=START-OF-DATA\n).*(?=\nEND-OF-DATA)"
(?<=START-OF-DATA\n)
和(?=\nEND-OF-DATA)
是环视断言在perlre描述,即它们用于匹配,但不包括在结果。
不错,使用准备,但是行开始数据和数据结束被打印:/请尝试改进你的命令行,以避免打印这两行。玩得开心:-)干杯 – olibre 2014-09-11 12:29:07
@olibre:感谢您指出。我添加了改进的命令行。 – 2014-09-11 16:53:25
太好了。正是我在找什么......你们很快就掉了标记我必须说:)再次感谢 – tasslebear 2014-09-11 11:47:47