如何获取shell脚本以正确调整数组值?

时间:2012-02-03 22:14:08

标签: shell sed

我有一个非常棒的shell脚本,可以很好地工作:获取一串Unicode值并将它们随机播放。问题是我需要确保每个值都在字符串中的不同位置。

例如,如果我的字符串是(只使用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社区的人。任何人都可以告诉我如何修改它,以确保字符串中任何地方的字符不会意外地在同一个地方结束吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

也许它没有用,因为我没有看到perl标签,但我会将这个工具用于工作。该脚本有两个参数,一个用于读取unicode字符串的输入文件和一个用于编写混洗字符串的输出文件。

script.pl的内容:

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;
}

infile的内容:

&#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

答案 1 :(得分: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