I guess you are out of luck to do this using one gradient but here is an idea that rely on mask where you will need at least 3 gradient to create the holes. The good thing is that the gradient is the same so using CSS variables we can see it as one gradient.
body {
  background-color: #222;
}
a {
  color: white;
  font-size: 30px;
  text-decoration: none;
  position: relative;
  display: inline-block;
  overflow: hidden;
}
a:before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: -150%;
  height: 2px;
  background: currentcolor;
  --grad: linear-gradient(to right, white calc(50% - 5px), transparent calc(50% - 5px) calc(50% + 5px), white 0);
  -webkit-mask: var(--grad), var(--grad), var(--grad);
  -webkit-mask-size: 230% 100%, 280% 100%, 350% 100%;
  -webkit-mask-position: 100% 0;
  -webkit-mask-composite: destination-in;
  mask: var(--grad), var(--grad), var(--grad);
  mask-size: 230% 100%, 280% 100%, 350% 100%;
  mask-position: 100% 0;
  mask-composite: intersect;
  animation: move 4s infinite ease-out;
}
@keyframes move {
  100% {
    -webkit-mask-position: 54% 0;
    mask-position: 54% 0;
  }
}
<a href="#">Animated link underline</a>
 
 
The mask part isn't difficult. All the trick rely on the gradient and position animation.
here is a better illustration to understand the trick. The green square are the holes in the previous code:
body {
  background-color: #222;
}
a {
  color: white;
  font-size: 30px;
  text-decoration: none;
  position: relative;
  display: inline-block;
  overflow:hidden;
}
a:before {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: -150%;
  height: 8px;
  --grad: linear-gradient(to right, transparent calc(50% - 5px), green calc(50% - 5px) calc(50% + 5px), transparent 0);
  background: var(--grad), var(--grad), var(--grad);
  background-size: 230% 100%, 280% 100%, 350% 100%;
  background-position: 100% 0;
  animation: move 4s infinite ease-out;
}
@keyframes move {
  100% {
    background-position: 54% 0;
  }
}
<a href="#">Animated link underline</a>
 
 
Related question to understand the calculation: Using percentage values with background-position on a linear-gradient
Another idea using only background:
body {
  background-color: #222;
}
a {
  color: white;
  font-size: 30px;
  text-decoration: none;
  padding-bottom:5px;
  background:
    linear-gradient(to right, 
      currentColor 0 80%,
      transparent  0 calc(80% + 10px),
      currentColor 0 85%,
      transparent  0 calc(85% + 10px),
      currentColor 0 90%,
      transparent  0 calc(90% + 10px),
      currentColor 0) bottom right/1000% 2px no-repeat;
  animation:move 2s linear infinite;
}
.alt {
  -webkit-box-decoration-break: clone;
}
@keyframes move {
  100% {
     background-size:calc(100% + 60px) 2px;
     background-position:bottom 0 right -60px;
  }
}
<a href="#">Animated link underline</a>
<br>
<br>
<a href="#" style="color:red;">Animated multil line<br> underline</a>
<br>
<br>
<a href="#" class="alt" style="color:pink;">Animated multil line<br> underline</a>