2012-02-03 48 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