【问题标题】:How to pipe a file back into a loop in bash?如何将文件通过管道传输回bash中的循环?
【发布时间】:2013-10-28 15:43:53
【问题描述】:

我试图想办法从文件中删除一对行,该对中的第一行包含一个唯一的 id,第二行是一个字符串。我在想一些类似于

的东西
for i in $(cat idlist.txt ); do grep -v -A1 $i file1 

但是我不确定如何在每次迭代时将循环的输出通过管道传回其中?有什么建议吗?

我要修改的文件基本上是这样的格式

uniqueID.1
OJNEFONEOIWENWEJNEWEJ
uniqueID.2
HHTHANJAHTNTHAJNTEOEJ

我想删除一些 id + 字符串。

谢谢

【问题讨论】:

  • sed -i 可以很好地解决这个问题。显示要删除的线条的图案,我们可能会为您提供帮助。关于你的方法,也许grep ... file > new_file && mv new_file file 可以做到。
  • 谢谢!我认为在循环结束时使用 mv 应该可以很好地完成它。

标签: bash loops for-loop


【解决方案1】:

awk 在这种情况下可能是一个不错的工具选择。这是基本思想的快速版本,包含在 bash 脚本中:

#!/bin/bash

awk '
FNR == 1 { filenum++ }
filenum == 1 { ids[$0] = 1 }
filenum == 2 {
    if ((FNR % 2) == 1) { id = $0 }
    else if (ids[id] != 1) { print id; print }
}
' idlist.txt file.txt

想法是通过将要忽略的标签添加到关联数组ids来处理idlist文件,然后成对处理第二个文件,注意第一行的id,然后打印它和下一个如果 id 不在 ids 中,则为该行。

如果您需要“就地”修改文件,与已经建议的 mv 相同的东西可以在这里工作。

成绩单:

$ cat idlist.txt 
id.2
id.4
id.6
$ cat file.txt 
id.1
stuff 1
id.2
stuff 2
id.3
stuff 3
id.4
stuff 4
id.5
stuff 5
id.6
stuff 6
id.7
stuff 7
$ ./skipper.sh 
id.1
stuff 1
id.3
stuff 3
id.5
stuff 5
id.7
stuff 7

【讨论】:

    【解决方案2】:

    为列表中的每个模式读取和写入文件似乎效率很低。最好只读取和处理一次文件,一次删除所有 id。

    如何执行此操作取决于您在该文件 idlist.txt 中获得的 ID 类型。从您将模式传递给grep 的方式来看,它们似乎必须是单词或者可能是简单的正则表达式,因此您可以尝试以下方法。

    首先,将 ID 转换为 sed 程序:

    PROGRAM=$(while read ID; do echo "/$ID/{N;d;}"; done < idlist.txt)
    

    然后使用sed 运行程序并就地更新文件:

    sed -i '' -e "$PROGRAM" -- file1
    

    程序的工作方式是/$ID/匹配包含id的行,然后N命令从文件中读取下一行,d命令删除这两行。其他行打印正常。 (显然这取决于$ID 是一个有效的基本正则表达式,不包含/ 字符。)

    如果您有一个接受“扩展正则表达式”的sed 版本(GNU 版本程序的-r 选项,或BSD 版本的-E 选项),那么您可以编译所有将您的 ID 转换为单个正则表达式:

    PROGRAM=$(printf '/('; tr '\n' '|' < idlist.txt; printf '.^)/{N;d;}')
    sed -r -i '' -e "$PROGRAM" -- file1
    

    (这里.^是一个不可能匹配的正则表达式;它跟在正则表达式的最后一个|之后,以确保交替中的最后一个子句没有匹配。)

    【讨论】:

      猜你喜欢
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 2017-02-08
      相关资源
      最近更新 更多