Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 减少while循环的Unix脚本执行时间_Bash_Unix_Parallel Processing - Fatal编程技术网

Bash 减少while循环的Unix脚本执行时间

Bash 减少while循环的Unix脚本执行时间,bash,unix,parallel-processing,Bash,Unix,Parallel Processing,有一个包含以下数据的参考文件“names.txt”: Tom Jerry Mickey 注意:文件“names.txt”中有20k行 参考文件“names.txt”中的每个键都有另一个带多行分隔符的文件,如下所示: Name~~Id~~Marks~~Column4~~Column5 注意:分隔文件中大约有30列: 分隔文件看起来像: Tom~~123~~50~~C4~~C5 Tom~~111~~45~~C4~~C5 Tom~~321~~33~~C4~~C5 . . Jerry~~222~~

有一个包含以下数据的参考文件“names.txt”:

Tom
Jerry
Mickey
注意:文件“names.txt”中有20k行

参考文件“names.txt”中的每个键都有另一个带多行分隔符的文件,如下所示:

Name~~Id~~Marks~~Column4~~Column5
注意:分隔文件中大约有30列:
分隔文件看起来像:

Tom~~123~~50~~C4~~C5
Tom~~111~~45~~C4~~C5
Tom~~321~~33~~C4~~C5
.
.
Jerry~~222~~13~~C4~~C5
Jerry~~888~~98~~C4~~C5
.
.

需要从分隔文件中为“Marks”列中具有最高值的文件“names.txt”中的每个键提取行
因此,对于文件“names.txt”中的每个键,输出文件中将有一行
下面是我正在使用的unix中截取的代码,它工作得非常好,但执行脚本大约需要2个小时

while read -r line; do
   getData `echo ${line// /}`
done < names.txt

function getData
{
   name=$1
   grep ${name} ${delimited_file} | awk -F"~~" '{if($1==name1 && $3>max){op=$0; max=$3}}END{print op} ' max=0 name1=${name} >> output.txt
}
读取-r行时
;做
getData`echo${line//}`
donemax){op=$0;max=$3}}}END{print op}'max=0 name1=${name}>>output.txt
}

是否有任何方法可以并行化此操作并减少执行时间。只能使用shell脚本

优化bash脚本的经验法则:
输入的大小不应影响程序运行的频率

您的脚本速度很慢,因为bash必须运行该函数20k次,其中包括启动
grep
awk
。仅仅启动程序就需要花费大量的时间。因此,尝试一种程序启动次数恒定的方法

以下是一种方法:

  • 处理第二个文件,使每个名称只保留带有最大标记的行。
    可以使用
    sort
    awk
    sort
    uniq-f
    +Schwartzian变换来完成。
  • 然后只保留那些名称出现在
    names.txt
    中的行
    轻松使用
    grep-f
  • sort-t'~'-k1,1-k5,5nr文件2|
    awk-F'~''1美元=最后{打印;最后=$1}'|
    
    grep-f优化bash脚本的经验法则:
    输入的大小不应影响程序运行的频率

    您的脚本速度很慢,因为bash必须运行该函数20k次,其中包括启动
    grep
    awk
    。仅仅启动程序就需要花费大量的时间。因此,尝试一种程序启动次数恒定的方法

    以下是一种方法:

  • 处理第二个文件,使每个名称只保留带有最大标记的行。
    可以使用
    sort
    awk
    sort
    uniq-f
    +Schwartzian变换来完成。
  • 然后只保留那些名称出现在
    names.txt
    中的行
    轻松使用
    grep-f
  • sort-t'~'-k1,1-k5,5nr文件2|
    awk-F'~''1美元=最后{打印;最后=$1}'|
    
    grep-f非常好!“我认为,
    grep-Fwf names.txt
    足以匹配名称——当然,这取决于我们没有看到的数据。”听到这个消息我很高兴。这个命令在你的文件上运行了多长时间(而不是2小时)?@Socowi大约2分钟,真是难以置信!我不想修改现有的文件,所以必须为名称创建一个临时文件,因为names.txt文件不仅具有names@SupratimDas如果您的真实文件
    names.txt
    有不同的格式,您应该在问题中显示它。使用
    sed
    命令提取名称可能很容易,而无需使用临时文件。@Bodo感谢您的提示。是的,我最终使用了sed命令来代替临时文件的创建。非常好!“我认为,
    grep-Fwf names.txt
    足以匹配名称——当然,这取决于我们没有看到的数据。”听到这个消息我很高兴。这个命令在你的文件上运行了多长时间(而不是2小时)?@Socowi大约2分钟,真是难以置信!我不想修改现有的文件,所以必须为名称创建一个临时文件,因为names.txt文件不仅具有names@SupratimDas如果您的真实文件
    names.txt
    有不同的格式,您应该在问题中显示它。使用
    sed
    命令提取名称可能很容易,而无需使用临时文件。@Bodo感谢您的提示。是的,我最终使用了sed命令来替换临时文件的创建。
    sort -t'~' -k1,1 -k5,5nr file2 |
    awk -F'~~' '$1!=last{print;last=$1}' |
    grep -f <(sed 's/.*/^&~~/' names.txt)