如何从文件中的同一行随机选择字符串

How To Randomly Choose Strings From Same Line In File

我读过这个 post Select random lines from a file in bash and 但是它们并不专门用于需要保持相同顺序的一组行。我还使用 cut 命令搜索了是否有任何随机化选项。

我的尝试:

我正在尝试用新行替换空格,然后随机排序,然后使用 Head 获取随机字符串(对于每一行)。

cat file1.txt | while read line; do echo $line | sed 's/ /\n/g' | sort -R | head -1

虽然这确实完成了一个随机字符串的基本工作,但我想知道是否有更好更有效的方法来编写这段代码?这样,我可以添加选项以获取 1-2 个随机字符串,而不仅仅是一个。

这里是file1.txt:

#Sample #Example #Whosebug #Question
#Easy #Simple #Code #Examples #Help
#Support #Really #Helps #Everyone #Learn

这是我想要的输出(随机值):

#Question
#Code #Examples
#Helps

如果您知道实现此代码的更好方法,我将非常感谢您的积极投入和支持。

使用 AWK:

%awk 'BEGIN { srand() } { print $(1+int(rand()*NF))}' data.txt

#Question
#Help
#Support

您可以将其修改为 select 每行 2 个(或更多)随机单词(重复),方法是重复 $(rand...) 构造,相应的次数(或定义用户函数这样做)。

从每一行 w/o 重复(按位置)中选择 N 个单词有点棘手:

awk '
BEGIN { N=2; srand() } 
{ 
    #Collect fields into an array (w)
    delete w;
    for(i=1;i<=NF;i++) w[i]=$i; 

    #Randomize Array (Fisher–Yates style)
    for(j=NF;j>=2;j--) { 
       r=1+int(rand()*(j));
       if(r!=j) { 
          x=w[j]; w[j]=w[r]; w[r]=x; 
       } 
    }

    #Take N first items off the randomized array 
    for(g=1;g<=(N<NF?N:NF);g++) {
       if(g>1) printf " "
       printf w[g];       
    }   
    printf "\n"
}' data.txt

N - 是每行要选择的(最大)单词数。

要在每行中随机选择(最多 N)个项目,请像这样修改代码:

awk '
BEGIN { N=2; srand() } 
{ 
    #Collect fields into an array (w)
    delete w;
    for(i=1;i<=NF;i++) w[i]=$i; 

    #Randomize Array (Fisher–Yates style)
    for(j=NF;j>=2;j--) { 
       r=1+int(rand()*(j));
       if(r!=j) { 
          x=w[j]; w[j]=w[r]; w[r]=x; 
       } 
    }

    #Take L < N first items off the randomized array 
    L=1+int(rand()*N);
    for(g=1;g<=(L<NF?L:NF);g++) {
       if(g>1) printf " "
       printf w[g];       
    }   
    printf "\n"
}' data.txt

每行将打印 1 或 2 (N) 个随机选择的单词。

这段代码仍然可以优化一点(即只打乱数组的前 L 个元素),但它比 [= 快 2 或 3 数量级 34=] 基于解决方案。

尝试 bash

cat file1  | xargs -n1  -I@ bash -c "output_count=2; \
   line=$(echo \"@\"); \
   words=$(echo  ${line} | wc -w); \
   for i in  $(eval echo \"{1..${output_count}}\"); do \
      select=$((1 + RANDOM % ${words})); \
      echo  ${line} | cut -d \" \" -f ${select} | tr '\n' ' '; \
   done;
   echo \" \" "

假设文件名为 file1。 为了更改随机选择的单词数,请将不同的数字设置为 output_count

打印

$ cat file1  | xargs -n1  -I@ bash -c "output_count=2; \
   line=$(echo \"@\"); \
   words=$(echo  ${line} | wc -w); \
   for i in  $(eval echo \"{1..${output_count}}\"); do \
      select=$((1 + RANDOM % ${words})); \
      echo  ${line} | cut -d \" \" -f ${select} | tr '\n' ' '; \
   done;
   echo \" \" "
#Example #Example
#Examples #Help
#Support #Learn
$ cat file1  | xargs -n1  -I@ bash -c "output_count=2; \
   line=$(echo \"@\"); \
   words=$(echo  ${line} | wc -w); \
   for i in  $(eval echo \"{1..${output_count}}\"); do \
      select=$((1 + RANDOM % ${words})); \
      echo  ${line} | cut -d \" \" -f ${select} | tr '\n' ' '; \
   done;
   echo \" \" "
#Question #Whosebug
#Help #Help
#Everyone #Learn

这就是解决方案

while read -r line; do echo "$line" | grep -oP '(\S+)' | shuf -n $((RANDOM%2+1)) | paste -s -d' '; done < file1.txt

这可能对你有用 (GNU sed):

sed 'y/ /\n/;s/.*/echo "&"|shuf -n$((RANDOM%2+1))/e;y/\n/ /' file

将每行中的空格替换为换行符并使用 seds 替换 e 标志,将每组行传递到 shuf -n 命令中 .