【问题标题】:Is there anything similar to logical AND that can be used in a bash script?是否有任何类似于逻辑 AND 的东西可以在 bash 脚本中使用?
【发布时间】:2013-08-08 09:47:07
【问题描述】:

有没有办法在 bash 脚本中同时读取两个文件?类似于编程语言示例中 & 的用法:

for i in $(cat filea.txt) & for j in $(cat fileb.txt)
do
    if "$j" = "$i"
    then echo "$i"
    fi
done

含义:我希望将 filea 的第 1 行与 fileb 的第 1 行进行比较,并将 filea 的第 2 行与 fileb 的第 2 行进行比较,依此类推。

【问题讨论】:

  • 我认为没有这样的结构。如果有,它将高度特定于bash
  • 我相信你正在寻找 bash 中的锁步迭代
  • 什么是$cat?我看不出如何在没有反引号 `cat filea.txt` 的情况下在这里执行 cat 命令。甚至选择单词,而不是行。 (乔纳森提供的更正也是如此。)
  • @SnakesandCoffee:我在 Bash 4.2 参考手册中找不到 'lock-step' 或 'lockstep' ......你能详细说明你在说什么吗?它是实际功能,还是“需要什么”?
  • @JonathanLeffler 听起来像是他编造的。但是,如果我们也有办法一次提取一行,则将这两个文件交错在一起可能会有所帮助:stackoverflow.com/questions/4011814/…

标签: bash


【解决方案1】:

你可以做的是比较行而不是单词,这有点扭曲,但是:

while read -r -u 3 line1 && read -r -u 4 line2
do
    if [ "$line1" = "$line2" ]
    then echo "$line2"
    fi
done 3<filea.txt 4<fileb.txt

我已经明确地使用文件描述符 3 和 4 来表示对称(Polya:“尽量对称地对待对称的东西,不要肆意破坏任何自然对称”);这也是可能的,但写得不太清楚:

while read -r line1 && read -r -u 3 line2
do
    if [ "$line1" = "$line2" ]
    then echo "$line2"
    fi
done <filea.txt 3<fileb.txt

read -u 代表什么,3 和 4 代表什么?

阅读精美手册 — bash 手册可在线获取,如果您还没有将其加入书签,现在是加入书签的好时机。

-ufd 选项的意思是“从指定的文件描述符(示例代码中的 3 或 4)而不是从标准输入(当然是文件描述符 0)读取. 3 和 4 代表要读取的文件描述符。在while 循环期间,代码从filea.txt 重定向文件描述符3 和从fileb.txt 重定向文件描述符4。任何读取文件描述符 3 的进程都会从filea.txt 获取数据;同上 4. 该脚本指示一个 read 命令从 3 读取,另一个从 4 读取,read 读取行,因此净效果是,虽然 filea.txtfileb.txt 都有可用数据,但循环将运行,比较两行并打印。

如果您的目标是打印两个文件之间共有的行,那么使用 comm 命令会更好 — 请参阅 Jonas Elfströmanswer 了解实现此目的的好方法。

假设您的目标是从两个文件中并行读取 ,我无法立即想到在 bash 中执行此操作的另一种方法。如果您需要两个文件中的 words 并行(这是 for i in $(&lt;filea.txt) 符号所给出的),您可能需要将 process substitution 与 I/O 重定向一起使用:

while read -r -u 3 word1 && read -r -u 4 word2
do
    if [ "$word1" = "$word2" ]
    then echo "$word2"
    fi
done 3< <(printf "%s\n" $(<filea.txt)) 4< <(printf "%s\n" $(<fileb.txt))

还有其他方法可以实现这一点,特别是使用tr 而不是printf,如果文件很大(很多兆字节)会更好。

【讨论】:

  • read -u 代表什么? 3 和 4 代表什么?
  • @user2613272 根据help read, -u 请求特定的文件描述符。 3 和 4 是文件描述符。在后一个示例中,他正在从标准输入中读取数据。
  • -r 怎么样?究竟是做什么用的?
  • @Potatoswatter:我想help 命令是 SCCS 的一部分的日子已经一去不复返了。
  • 所以您还没有学会如何阅读手册,或者按照 Potatoswatter 的建议使用来自help read 的信息? help read 部分表示:如果给出了-r 选项,这表示“原始”输入,并且反斜杠转义被禁用。 要了解更多关于这意味着什么,请阅读手册。
【解决方案2】:

如果目标是输出两个文件中相同的行,那么您可以使用comm

comm -12 file1 file2

但如果您确实需要单步执行两个文件,那么您可以使用文件描述符。

#! /bin/bash
while read -r lineF1 <&3 && read -r lineF2 <&4; do
  echo "$lineF1"
  echo "$lineF2"
done 3<file1 4<file2

【讨论】:

  • +1 用于横向思考——尽管我认为它忽略了问题的重点,即是否有办法并行处理两个文件的行。
  • 是的,我用过它,效果很好;还有一个问题,我如何排除 file2 的最后 3 行;我不希望它们出现在我的输出中
  • 当任一文件结束时,此变体将停止。文件中的行数是否相等?
猜你喜欢
  • 2018-11-25
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 2011-12-04
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多