Как вставить переменную в переменную в случайном месте?

В: Как вставить переменную $ b в по-настоящему случайное место в переменной $ a?

Пример содержимого переменной INPUT:

$ echo $a árvíztűrő tükörfúrógép $ echo $b ZZ 

ВЫВОД

 $ ./somemagicscript.sh árvíztűrő tüköZZrfúrógép $ ./somemagicscript.sh árvíztűrő tükörfúrZZógép $ ./somemagicscript.sh árvíztűrZZő tükörfúrógép $ ./somemagicscript.sh árvíztűrő tZZükörfúrógép 

UPDATE: текущие ответы не совсем хороши, поскольку в OpenBSD он иногда помещает символ « » помимо вставленной переменной. : \

Возможно, чем когда вставленная переменная находится рядом с многобайтовым символом.

 sed "s/.\{$(($RANDOM%${#a}))\}/&$b/" <<< $a 

где:

  • $RANDOM псевдослучайное значение от 0 до $RAND_MAX (обычно 0x7fff == 32767 )
  • ${#a} длина целевой строки
  • $((...%...)) выводит результат от деления
  • .{n} соответствует первым n символам входной строки
  • s/.../&$b/ шаблонов + $b

Другие ответы дают решения для sed и awk. Если ваш sed и awk не поддерживают многобайтовые символы, все равно есть хороший шанс, что ваш bash их поддержит, так что это решение с чистым башем.

Сначала мы выбираем случайное число между 0 и длиной строки $a , включительно, так что строка $b может быть вставлена ​​между любыми двумя символами $a , или перед первым, или после последнего. Это сохраняется в mid . Затем мы создаем строку, состоящую из (с использованием псевдокода) a[0..mid-1] + b + a[mid..$] (индексирование начинается с 0).

 $ cat ./multi #!/bin/bash a='árvíztűrő tükörfúrógép' b='ZZ' len=${#a} echo "a is ${a} len is ${len}" mid=$(((len + 1) * $RANDOM / 32767)) c="${a:0:$mid}${b}${a:$mid}" echo "$c" $ ./multi a is árvíztűrő tükörfúrógép len is 22 árvíztűrő tükörfúrógéZZp $ ./multi a is árvíztűrő tükörfúrógép len is 22 árvízZZtűrő tükörfúrógép $ ./multi a is árvíztűrő tükörfúrógép len is 22 árvíztűrő tükörZZfúrógép $ ./multi a is árvíztűrő tükörfúrógép len is 22 ZZárvíztűrő tükörfúrógép 

попытка в awk:

 awk "{srand(); i=int(rand()*length(\$0)); print substr(\$0,0,i)\"${b}\"substr(\$0,i)}" <<< $a 

В Perl (подходит для сценария оболочки):

 perl -CSA -e '$_=shift; substr($_,int(rand(1+length)),0,shift); print' "$a" "$b" 

Обратите внимание на разные позиции 1 + длины: в начале строки и после каждого символа.

ETA: И да, -CSA указывает, что аргументы командной строки и стандартный вывод (и другие стандартные дескрипторы файлов) используют UTF-8 (многобайтовый).