使用批处理

时间:2016-12-30 13:19:45

标签: windows batch-file

我有一个文件,其中每一行都有以下格式:

1yjo    ASN 1   A   GLN 3   B   8.85

我必须提取第二个标记等于PHE 的每一行,第五个标记等于LEU 反之亦然。例如:

2beg    LEU 17  A   VAL 18  C   8.76
2beg    LEU 17  A   PHE 19  A   7.2
2beg    PHE 19  A   ALA 21  B   8.88
2beg    PHE 19  D   LEU 34  E   13.28

如果这是输入文件,我将不得不提取第二行和第四行。最好将它们提取到一个单独的文件中。

这是我迄今为止所做的尝试:

@echo off
set inputfile=a.dat
for /F "tokens=1,2,3,4,5,6,7,8" %%a in (%inputfile%) do (
if %%b == "LEU" and %%e == "PHE" do (
@echo %%b %%e
)
)

...但它只是复制整个输入文件,即IF条件没有任何影响...

编辑:我也尝试过:

...
if %%b == "LEU" (
if %%e == "PHE" (
@echo %%a %%b %%c %%d %%e %%f %%g %%h
)
)
...

......并且它不会复制任何内容。

我也不确定我是否可以使用"和"和"或"运算符,或者我必须使用多个嵌套if ...

我该怎么做?

4 个答案:

答案 0 :(得分:2)

我刚刚找到了解决方案:

@echo off
for /F "tokens=1,2,3,4,5,6,7,8" %%a in (%1) do (
    if "%%b" == "%2" (
        if "%%e" == "%3" (
            @echo %%a %%b %%c %%d %%e %%f %%g %%h >> output.txt
        )
    )
    if "%%b" == "%3" (
        if "%%e" == "%2" (
            @echo %%a %%b %%c %%d %%e %%f %%g %%h >> output.txt
        )
    )
)

我还使用了输入文件名(%1)和两个字符串(%2和%3)的输入参数,它就像一个魅力:)

答案 1 :(得分:1)

要提取相关的行,我只想使用基本管道。

在cmd窗口中这样:

Find " LEU "<"a.dat"|Find " PHE ">Output.txt

...或来自批处理文件:

@Find " LEU "<"a.dat"|Find " PHE ">Output.txt

[编辑/]

作为基于以下评论的更新,我的想法是在批处理文件中使用findstr

@FindStr/RC:"\<LEU .* PHE\>" /C:"\<PHE .* LEU\>" a.dat>Output.txt

答案 2 :(得分:1)

您可以通过单个FINDSTR正则表达式搜索非常有效地(快速地)获得答案,但由于FINDSTR的正常表达能力瘫痪,搜索很尴尬。我假设这些标记始终是标记之间的空格,而不是制表符。我使用了行继续来使命令更容易阅读。

findstr /r /c:"^[^ ][^ ]*  *PHE  *[^ ][^ ]*  *[^ ][^ ]*  *LEU "^
           /c:"^[^ ][^ ]*  *LEU  *[^ ][^ ]*  *[^ ][^ ]*  *PHE " input.txt >output.txt

如果你可以依赖LEU和PHE永远不会出现在第二和/或第五代币之外的任何地方,那么你可以大大简化搜索:

findstr "PHE.*LEU LEU.*PHE" input.txt >output.txt

使用正确的正则表达式工具,精确搜索更加简单。您可以将powershell或JScript用于本机脚本正则表达式解决方案。或者您可以下载Windows版本的grep,或者......

因为我已经拥有它,所以我会使用我的JREPL.BAT regular expression utility。 JREPL是纯脚本(混合批处理/ JScript),可以在任何Windows机器上从XP开始本地运行 - 不需要第三方exe文件。可以从命令行通过jrepl /?jrepl /??获取完整文档以获取分页帮助。

jrepl "^\S+\s+(PHE|LEU)\s+\S+\s+\S+\s+(?!\1)(PHE|LEU)\s" "" /k 0 /f input.txt /o output.txt

如果您不熟悉正则表达式:

  • ^标记了行的开头
  • \S+匹配一个或多个非空格字符(任意令牌)
  • \s+代表一个或多个空白字符(令牌分隔符)
  • (PHE|LEU)匹配PHE或LEU,并捕获匹配
  • 如果下一个字符串与先前捕获的匹配匹配,则
  • (?!\1)是否定的预测失败。 (不想匹配PHE-PHE或LEU-LEU)

通常JREPL用于查找/替换字符串。 /k 0选项指示JREPL忽略replace参数,只打印出与搜索字符串匹配的所有行。

大多数正确的正则表达式工具都可以使用相同的正则表达式。

答案 3 :(得分:1)

这是与vtomic85相同的解决方案,但是更简单,更快捷。此版本还保留原始间距。

@echo off
(for /F "delims=" %%a in (%1) do (
   for /F "tokens=2,5" %%b in ("%%a") do (
      if "%%b%%c" equ "%2%3" echo %%a
      if "%%b%%c" equ "%3%2" echo %%a
   )
)) > output.txt