在bash / awk / sed中用随机字母替换字母

时间:2015-12-13 19:06:47

标签: regex linux bash awk sed

我的文件内容低于

cat input.txt

地图:022 HighValue2 02ABC1232 PACKET v1.1

任务:022 HighValue2 02ABC1232 PACKET v1.1

地图:023 LowValue3 23ABCDe123 IP v1.3

任务:023 LowValue3 23ABCDe123 IP v1.3

地图:024 MediumValue3452 02ABwe12325 HOST v1.2

任务:024 MediumValue3452 02ABwe12325 HOST v1.2

我想用任何随机字母替换任务行中粗体字母的字母而不更改数字。例如,所需的输出应为

地图:022 HighValue2 02hKQ1232 PACKET v1.1

任务:022 HighValue2 02hKQ1232 PACKET v1.1

地图:023 LowValue3 23wpNY123 IP v1.3

任务:023 LowValue3 23wpNY123 IP v1.3

地图:024 MediumValue3452 02QZNT12325 HOST v1.2

任务:024 MediumValue3452 02QZNT12325 HOST v1.2

@karakfa,@ Ed Morton和@Cyrus给出了很好的答案。但awk版本在我的情况下不起作用,而bash版本工作正常。我想要更新的bash版本和工作awk版本为我更新的输入文件。

我希望我足够清楚。

3 个答案:

答案 0 :(得分:1)

使用bash:

{
  "explain": true,
  "from": 0,
  "size": 10,
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "Gender": {
                  "query": "F",
                  "boost": 10.0
                }
              }
            }
          ]
        }
      }
    }
  }
}

以您的文件作为输入输出:

task: 022 HighValue2 02XeM1232 PACKET v1.1
task: 023 LowValue3 23lJBXx123 IP v1.3
task: 024 MediumValue3452 02Ochs12325 HOST v1.2

更新

#!/bin/bash

array=({a..z} {A..Z})                     # all 52 possible characters

while read -r a b c d e; do               # loop with all lines of "file"
  echo -n "$a $b $c "
  for ((i=0;i<${#d};i++)); do             # loop with all characters of $d
    if [[ ${d:$i:1} =~ [a-zA-Z] ]]; then
      printf "%s" ${array[RANDOM % 51]}   # print random character from $array
    else
      printf "%s" ${d:$i:1}               # print current character
    fi
  done
  echo " $e"
done < file

输出:

map: 022 HighValue2 02ABC1232 PACKET v1.1
task: 022 HighValue2 02Arb1232 PACKET v1.1
map: 023 LowValue3 23ABCDe123 IP v1.3
task: 023 LowValue3 23dRfWa123 IP v1.3
map: 024 MediumValue3452 02ABwe12325 HOST v1.2
task: 024 MediumValue3452 02cfdN12325 HOST v1.2

答案 1 :(得分:1)

$ cat tst.awk
BEGIN {
    lgth = split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",new,"")
    srand()
}
{
    split($4,old,"")
    $4 = ""
    for (i=1;i in old;i++) {
        $4 = $4 (old[i] ~ /[[:alpha:]]/ ? new[int(rand()*lgth+1)] : old[i])
    }
    print
}

$ awk -f tst.awk file
task: 022 HighValue2 02bQh1232 PACKET v1.1
task: 023 LowValue3 23vxDXl123 IP v1.3
task: 024 MediumValue3452 02huyO12325 HOST v1.2

$ awk -f tst.awk file
task: 022 HighValue2 02AZk1232 PACKET v1.1
task: 023 LowValue3 23AHXkl123 IP v1.3
task: 024 MediumValue3452 02YYia12325 HOST v1.2

以上内容至少可以与GNU awk一起使用,但是可能会有一些awks不会通过分隔成字符来处理NULL字符串上的分裂,所以试试看看 - 还有其他填充方法数组或使用字符串,例如任何POSIX awk和大多数非POSIX awks:

$ cat tst.awk
BEGIN {
    new = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    lgth = length(new)
    srand()
}
{
    old = $4
    $4 = ""
    for (i=1;i<=length(old);i++) {
        $4 = $4 ( substr(old,i,1) ~ /[[:alpha:]]/ ? substr(new,int(rand()*lgth+1),1) : substr(old,i,1) )
    }
    print
}

$ awk -f tst.awk file
task: 022 HighValue2 02PeK1232 PACKET v1.1
task: 023 LowValue3 23zsyjH123 IP v1.3
task: 024 MediumValue3452 02XPtt12325 HOST v1.2

如果这不起作用,那么你真的需要获得一个新的awk,因为你正在使用的awk缺少关键功能,但同时 - 尝试将字符类[[:alpha:]]更改为字符列表{{ 1}}(或任何字符列表只包含您语言环境中的所有字母)。

答案 2 :(得分:0)

awk救援!

$ awk -f randomize.awk input1 
task: 022 HighValue2 02mpR1232 PACKET v1.1
task: 023 LowValue3 23hEkQj123 IP v1.3
task: 024 MediumValue3452 02zhtz12325 HOST v1.2

用随机字符替换第4个字段字符。

$ cat randomize.awk 

function r(k) { 
     s=""; 
     for(i=1;i<=k;i++) s = s substr(chars,rand()*n+1,1); 
     return s;
} 

BEGIN{
     chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     n = length(chars)
}

{
     match($4, /([0-9]+)([a-zA-Z]+)([0-9]+)/, a); 
     $4 = a[1] r(length(a[2])) a[3]
}

1           

PS。请注意,随机始终使用相同的序列。您可以将其设置为不同的序列,srand()可能带有时间戳。

更新:重写没有匹配功能

BEGIN{
   srand()
   chars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   n = length(chars)
}

{
   t="";
   for(j=1;j<=length($4);j++) {
      c = substr($4,j,1);
      r = substr(chars,rand()*n+1,1);
      t = t (c~/[a-zA-Z]/?r:c);
   }
   $4 = t;
   print
}