如何在shell脚本中异步运行迭代

时间:2017-07-18 12:14:35

标签: linux bash shell asynchronous scripting

我有几个.csv文件,如下所示。

  1. xyz0900@1#-1637746436.csv
  2. xxx0900@1#-1637746436.csv
  3. zzz0900@2#-1637746439.csv
  4. yyy0900@1#-1637746436.csv
  5. sss0900@2#-1637746439.csv
  6. 我编写了一个脚本来执行以下任务:

    1. 根据我们作为脚本参数传递的模式获取大文件。
    2. 合并具有相同模式的所有其他文件并创建新文件
    3. 从新文件中删除重复的标头。
    4. 根据作为参数传递的参数将新文件移动到目标。
    5.   

      示例:我正在通过“1637746436 @ home / dest1,1637746436 @ home / dest2”   脚本的第二个参数。下面的脚本将获取   图案(1637746436)。获取更大的文件并合并所有其他文件   文件(具有相同的模式)与它。将创建新文件,并将相同的文件移动到目标(home / dest1)。

      以下脚本将按顺序执行模式匹配和执行。

      如何使'for循环迭代'应该并行执行?我的意思是“1637746436 @ home / dest1,1637746436 @ home / dest2”的模式匹配应该同时执行(不是一个接一个地执行) )。

      请帮忙。

      $merge.sh /home/dummy/17 "1637746436@home/dest1,1637746439@home/dest2" 
      
      
       #!/bin/bash
       current=`pwd`
       source=$1
       destination=$2
       echo "$destination" | tr "," "\n" > $current/out.txt
       cat out.txt | cut -d "@" -f1 > $current/pattern.txt
      
       for var in `cat pattern.txt`
       do
       getBiggerfile=$(ls -Sl $source/*$var.csv | head -1)
       cd $source
       getFileName=$(echo $getBiggerfile | cut -d " " -f9-)
       newFileName=$(echo $getFileName | cut -d "@" -f1)
       cat *$var.csv >> $getFileName
       header=$(head -n 1 $getFileName)
      (printf "%s\n" "$header";
       grep -vFxe "$header" $getFileName
       ) > $newFileName.csv
       rm -rf *$var.csv
       cd $current
      
       for var1 in `cat out.txt`
       do
       target=`echo $var1 | cut -d "@" -f2`
       id=$(echo $var1 | cut -c-10)
       if [ $id = $var ]
       then
       mv $newFileName.csv $target
       fi
       done
      done
      

1 个答案:

答案 0 :(得分:1)

最干净的是使循环的内部成为一个函数,并在循环中调用函数,将它放在后台(子进程),然后等待后台(子进程)进程完成:

function do_the_thing(){
    source="$1"
    current="$2"
    var="$3"
    getBiggerfile=$(ls -Sl $source/*$var.csv | head -1)
    cd $source
    getFileName=$(echo $getBiggerfile | cut -d " " -f9-)
    newFileName=$(echo $getFileName | cut -d "@" -f1)
    cat *$var.csv >> $getFileName
    header=$(head -n 1 $getFileName)
    (printf "%s\n" "$header";
       grep -vFxe "$header" $getFileName
    ) > $newFileName.csv
    rm -rf *$var.csv
    cd $current

    for var1 in `cat out.txt`
    do
        target=`echo $var1 | cut -d "@" -f2`
        id=$(echo $var1 | cut -c-10)
        if [ $id = $var ]
        then
            mv $newFileName.csv $target
        fi
    done
}

for var in `cat pattern.txt`
do
    do_the_thing "$source" "$current" "$var" &
done

wait