2012-02-03 39 views
2

我有一个奇妙的shell脚本,它运行得非常漂亮:接受一串Unicode值并对它们进行洗牌。问题是我需要确保每个值都位于字符串中的不同位置。如何获得一个shell脚本来正确洗牌数组值?

例如,如果我的字符串(只用ASCII):

ABCDEFG

我需要知道,没有这些字符都将在同一地点洗牌后:

gbadcef将不起作用,因为“d”在同一个地方。以非常最后一个值,并把它首先会工作......

fabcde

...但它不给我,我需要应用程序的随意性。

实际的数据字符串是Unicode值,长,长,长分号分隔字符串:

₮„‮″⃝Ⴎ𠂮ž etc. 

这里的洗牌代码我目前有:

#!/bin/bash 
echo "Input Filename:"; 
read ifilename; 
echo "Output Filename:"; 
read ofilename; 
cat $ifilename | sed -r 's/(.[^;]*;)/ \1 /g' | tr " " "\n" | shuf | tr -d "\n" > $ofilename; 

这是一个伟大的,紧,我认为这是来自StackOverflow社区中某个人的精彩脚本。任何人都可以告诉我如何修改它,以确保字符串中的任何字符不会意外地出现在同一个地方?

谢谢你的帮助!

+3

你需要什么样的随机性?你的克制使得输出更少随机,而不是更多。 – 2012-02-03 22:27:36

+0

只要它“很好地洗牌”,它不必像它可能的那样随机。随机性并不重要,因为在“甲板”洗牌后,每个字符都处于不同的位置。 – user1149499 2012-02-03 22:48:36

+0

您现有的脚本可以很容易地修改为您的新需求。不要在所有字符之间添加空格,并用换行符替换它,请用换行符替换每个&符号。洗牌后,删除空行,并在每行的开头添加&符号。 – tripleee 2012-02-04 14:17:28

回答

0

也许它没有用,因为我没有看到perl标签,但我会使用该工具来完成这项工作。该脚本需要两个参数,一个是输入文件以读取unicode字符串,另一个是输出文件以写入混洗字符串。

内容script.pl

内容 infile
use warnings; 
use strict; 
use List::Util qw(shuffle); 

## Check arguments for two files, one for input and other for output. 
die qq[Usage: perl $0 <input-file> <output-file>\n] unless @ARGV == 2; 

## Open files. 
open my $ifh, qq[<], shift @ARGV or die qq[Cannot open argument file\n]; 
open my $ofh, qq[>], shift @ARGV or die qq[Cannot open argument file\n]; 


## Read from input file ... 
while (<$ifh>) { 

    ## Array with suffled characters. 
    my @shuffle; 

    ## Remove last newline character. 
    chomp; 

    ## Create an array with chars of input string. 
    my @f = split /;/; 

    ## Repeat: Shuffle array until no char keeps 
    ## its original position. 
    SHUFFLE: while (1) { 
     @shuffle = shuffle @f; 
     for my $i (0 .. $#f) { 
      next SHUFFLE if $shuffle[ $i ] eq $f[ $i ]; 
     } 
     last; 
    } 

    ## Print shuffled array. 
    printf $ofh qq[%s\n], join qq[;], @shuffle; 
} 

&#x020AE;&#x0201E;&#x0202E;&#x02033;&#x020DD;&#x010AE;&#x200AE;&#x0009E; 
&#x02043;&#x02099;&#x0ABCD;&#x02033;&#x020DD; 

使用正确的参数运行脚本:

perl script.pl infile outfile 

和执行后的outfile内容:

&#x020DD;&#x010AE;&#x02033;&#x0009E;&#x0201E;&#x020AE;&#x0202E;&#x200AE 
&#x02099;&#x0ABCD;&#x02033;&#x020DD;&#x02043 
+0

好的,我对perl不是很熟悉,但它不一定是bash。对于上述情况,是否可以通过对输入文件(将成为上述DATA部分的.txt文件)进行类似的查询来完成,并写入用户指定的输出文件?我也不确定为什么我用“for”循环运行脚本 - 我只需要为每个文件执行两次这样的操作(但我有数百个文件)。 – user1149499 2012-02-04 01:42:39

+0

@ user1149499:修改脚本以符合您的要求。 – Birei 2012-02-04 10:56:06

+0

这很好用!谢谢! – user1149499 2012-02-05 01:12:40

0

以下Bash脚本随机随机混合列表,同时防止字符占据先前的位置。

#!/bin/bash 
IFS=";" 
while read -r -a array 
do 
    num=${#array[@]} 
    for ((i = 0; i < num; i++)) 
    do 
     r=$i 
     while ((r == i)) || [[ ${new[r]} ]] 
     do 
      ((r = $RANDOM % num)) 
     done 
     new[r]=${array[i]} 
    done 
    echo "Input: ${array[*]}" 
    echo "Output: ${new[*]}" 
done 

例子:

$ charshuf < charfile 
Input: a;b;c;d;e;f;g;h;i;j;k;l 
Output: j;h;i;a;b;k;f;e;g;c;l;d 
Input: 1;2;3;4;5;6;7;8 
Output: 6;3;8;2;4;7;5;1