当前位置: 首页 > 知识库问答 >
问题:

GNU与自定义脚本并行执行字符串比较

张可人
2023-03-14

下面的script.sh将字符串的一部分(来自stdinbycating a csv file)与定义的字符串进行比较,并以特定格式报告差异

#!/usr/bin/env bash

reference="ABCDEFG"
ref_transp=$(echo "$reference" | sed -e 's/\(.\)/\1\n/g')
while read line; do
  line_transp=$(echo "$line" | cut -d',' -f2 | sed -e 's/\(.\)/\1\n/g')
  output=$(paste -d ' ' <(echo "$ref_transp") <(echo "$line_transp") | grep -vnP '([A-Z]) \1' | sed -E 's/([0-9][0-9]*):([A-Z]) ([A-Z]*)/\2\1\3/' | grep '^[A-Z][0-9][0-9]*[A-Z*]$')
  echo "$(echo ${line:0:35}, $output)"
done < "${1:-/dev/stdin}"

它打算以以下格式在一个非常大的文件中的多行上执行

XYZ,ABMDEFG

当我在管道中使用它时,它工作得很好:

cat large_file | ./find_something.sh

但是,当我尝试将它与并行一起使用时,我会得到这个错误:

$  cat large_file | parallel ./find_something.sh
./find_something.sh: line 9: XYZ, ABMDEFG : No such file or directory

这是什么原因造成的?如果我想在以后将输出重定向到单个文件,那么类似的东西应该是并行的吗?

不太重要的补充说明:我对我的字符串比较方法感到非常自豪,但如果有人有一种更快的方法,可以通过比较XYZ,C3M来获得XYZ,C3M,我也很高兴听到这个消息。

我应该说,我还想保留输出中每一行的顺序,对应于输入。使用并行可以吗?

共有2个答案

程胤运
2023-03-14

-k保持顺序。

#!/usr/bin/env bash

doit() {    
    reference="ABCDEFG"
    ref_transp=$(echo "$reference" | sed -e 's/\(.\)/\1\n/g')
    while read line; do
      line_transp=$(echo "$line" | cut -d',' -f2 | sed -e 's/\(.\)/\1\n/g')
      output=$(paste -d ' ' <(echo "$ref_transp") <(echo "$line_transp") | grep -vnP '([A-Z]) \1' | sed -E 's/([0-9][0-9]*):([A-Z]) ([A-Z]*)/\2\1\3/' | grep '^[A-Z][0-9][0-9]*[A-Z*]$')
      echo "$(echo ${line:0:35}, $output)"
    done
}
export -f doit

cat large_file | parallel --pipe -k doit
#or
parallel --pipepart -a large_file --block -10 -k doit

陶腾
2023-03-14

脚本接受来自文件的输入(默认为stdin),而parallel将输入作为参数传递,而不是通过stdin。从这个意义上说,并行更接近于xargs。

据推测,您希望large_file中的每一行都作为一个单元进行处理,可能是并行的。

这意味着您需要您的脚本一次只处理一行这样的行,并让并行多次调用您的脚本,每行一次。

因此,您的脚本应该如下所示:

#!/usr/bin/env bash

reference="ABCDEFG"
ref_transp=$(echo "$reference" | sed -e 's/\(.\)/\1\n/g')
line="$1"
line_transp=$(echo "$line" | cut -d',' -f2 | sed -e 's/\(.\)/\1\n/g')
output=$(paste -d ' ' <(echo "$ref_transp") <(echo "$line_transp") | grep -vnP '([A-Z]) \1' | sed -E 's/([0-9][0-9]*):([A-Z]) ([A-Z]*)/\2\1\3/' | grep '^[A-Z][0-9][0-9]*[A-Z*]$')
echo "$(echo ${line:0:35}, $output)"

然后您可以重定向到文件,如下所示:

cat large_file | parallel ./find_something.sh > output_file
 类似资料:
  • 我有两个数组列表,一个是字符串列表,第二个是Toggle按钮列表。现在我想比较两个数组中的字符串。请帮助我。

  • 问题内容: 我需要在Java字符串之间执行Diffs。我希望能够使用原始的string和diff版本重建字符串。有人用Java完成吗?你使用什么图书馆? 问题答案: 这个库似乎可以解决问题:google-diff-match-patch。它可以根据差异创建补丁字符串,并允许重新应用补丁。

  • 我正试图找到一个很好的方法,在并行地逐行读取时比较两个字符串。我之所以不使用equals方法,是因为字符串不完全相同,为了更准确,我举一个例子。 正如u所看到的,当我们逐行查看时,两个字符串都有相同的值(尽管并不完全相等,因为s2中也有\r)。现在,我知道我可以使用一些remove方法来清理“\r”,但由于字符串可能非常大,我更喜欢逐行循环,一旦字符串不相等,就会破坏我的逻辑。换句话说,我更喜欢只

  • 问题内容: 这个问题已经在这里有了答案 : Python If == true语句仅在readline的最后一行有效 (1个答案) 2年前关闭。 我试图将我的一行与一个字符串进行比较,但是这行不通。我正在读取一个html文件,我需要解析该文件以将该部分发送到字典,但是当我使用if将行之一与字符串进行比较时,匹配时不会返回True。 这是代码: 问题答案: 我认为这是因为它尝试读取字符串中的换行符:

  • 我试图编写一个程序,其中我必须做与模板(本质上是一个字符串)之间的字符串列表的比较。我不知道什么是使用的术语,但它将是更多的日志刮削程序,如果这是有帮助的。 null 这个想法是将输入语句(1-4)与模板字符串(a-b)匹配,如果它们匹配,那么我需要对它们进行操作。Like 1和4匹配句子b,但2不匹配。 提前感谢您的帮助/指示。