2

如何sed打印文件之间\begin{mcstas}\end{mcstas}文件中的所有大写单词foo.tex

以下示例包含 foo.tex 的最小示例:

\begin{mcstas}
DEFINE COMPONENT  child_name COPY parent_name
SETTING PARAMETERS (newpar1, newpar2) 
INITIALIZE COPY  parent_name EXTEND 
SAVE
\end{mcstas}
foo FALSE POSITIVE
\begin{mcstas}
DEFINE COMPONENT  name ...
\end{mcstas}
4

5 回答 5

6

正如您所问的那样,这有点棘手:“介于\begin{mcstas}\end{mcstas}”部分sed可以轻松完成,但“打印所有大写单词”部分最好使用grep而不是sed. 因此,如果您只想完成它,您可以执行以下操作:

$ sed '/\\begin{mcstas}/,/\\end{mcstas}/!d' foo.tex | grep -ow '[A-Z]\+'
DEFINE
COMPONENT
COPY
SETTING
PARAMETERS
INITIALIZE
COPY
EXTEND
SAVE
DEFINE
COMPONENT

以下是执行相同操作的单个sed命令(如您最初询问的那样)的外观:

$ sed -n '/\\begin{mcstas}/,/\\end{mcstas}/!d; s/\b/\n/g; :a; /^[A-Z]\+\n/P; s/[^\n]*\n//; ta' foo.tex
DEFINE
COMPONENT
COPY
SETTING
PARAMETERS
INITIALIZE
COPY
EXTEND
SAVE
DEFINE
COMPONENT
于 2013-09-22T19:40:45.977 回答
4

您可以使用 awk 吐出您想要的行,然后通过管道传递给 sed 并替换除大写字母之外的所有内容(我建议这样做是因为我总是无法使用 sed 来执行任何多行操作,但我更喜欢它而不是 awk)。

可能有更好的解决方案,但这是我想到的第一个:

awk '/begin/,/end/' yourfile.txt | sed 's/[^A-Z ]//g' | sed '/^$/d'

最后的最后一点只是删除了所有剩余的空行。

这会产生以下输出:

DEFINE COMPONENT   COPY
SETTING PARAMETERS
INITIALIZE COPY   EXTEND 
SAVE
DEFINE COMPONENT
于 2013-09-22T19:37:54.483 回答
2

单独使用

单线版:

perl -lne '/\\begin\{mcstas\}/../\\end\{mcstas\}/ and /\p{Lu}+/ and print $& for split;' file

扩展版:

perl -lne '
    if (/\\begin\{mcstas\}/ .. /\\end\{mcstas\}/) {
        /\p{Lu}+/ and print $& for split;
    }
' file

我们也可以使用 POSIX[[:upper:]]代替\p{Lu}or\p{Uppercase_Letter}

请参阅http://perldoc.perl.org/perluniprops.html#Properties-accessible-through-\p {}-and-\P{}

于 2013-09-22T19:50:11.743 回答
1
$ awk -v RS='[[:space:]]' '/\\(begin|end){mcstas}/{f=!f} f && /^[[:upper:]]+$/' file
DEFINE
COMPONENT
COPY
SETTING
PARAMETERS
INITIALIZE
COPY
EXTEND
SAVE
DEFINE
COMPONENT

或者如果您希望它们只打印一次:

$ awk -v RS='[[:space:]]' '/\\(begin|end){mcstas}/{f=!f} f && /^[[:upper:]]+$/ && !seen[$0]++' file
DEFINE
COMPONENT
COPY
SETTING
PARAMETERS
INITIALIZE
EXTEND
SAVE
于 2013-09-23T00:03:02.130 回答
1

另一个awk

awk '/\\end/{f=0} toupper($0)==$0 && NF;  /\\begin/{f=1}' RS=" |\n" file
于 2013-09-23T06:31:52.960 回答