如何从文件中的同一行随机选择字符串
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
命令中
.
我读过这个 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
命令中
.