Replacing a repeating number in a file with random numbers

后端 未结 1 1404
孤城傲影
孤城傲影 2021-01-19 10:44

I want to replace all occurrences of a number with a random number in each line of a file using \"sed\". For example, if my file has the number 892 in each line, I would lik

相关标签:
1条回答
  • 2021-01-19 11:07

    With GNU sed, you could do something like

    sed '/;892$/ { h; s/.*/echo $((RANDOM % 100 + 800))/e; x; G; s/892\n// }' filename
    

    ...but it would be much saner to do it with awk:

    awk -F \; 'BEGIN { OFS = FS } $NF == 892 { $NF = int(rand() * 100 + 800) } 1' filename
    

    To make sure that the random numbers are unique, amend the awk code as follows:

    awk -F \; 'BEGIN { OFS = FS } $NF == 892 { do { $NF = int(rand() * 100 + 800) } while(!seen[$NF]++) } 1'
    

    Doing that with sed would be too crazy for me. Be aware that this will only work only if there are less than 100 lines with a last field of 892 in the file.

    Explanation

    The sed code reads

    /;892$/ {                              # if a line ends with ;892
      h                                    # copy it to the hold buffer
      s/.*/echo $((RANDOM % 100 + 800))/e  # replace the pattern space with the
                                           # output of echo $((...))
                                           # Note: this is a GNU extension
      x                                    # swap pattern space and hold buffer
      G                                    # append the hold buffer to the PS
                                           # the PS now contains line\nrandom number
      s/892\n//                            # remove the old field and the newline
    }
    

    The awk code is much more straightforward. With -F \;, we tell awk to split the lines at semicolons, then

    BEGIN { OFS = FS }  # output field separator is input FS, so the output
                        # is also semicolon-separated
    $NF == 892 {        # if the last field is 892
                        # replace it with a random number
      $NF = int(rand() * 100 + 800)
    }
    1                   # print.
    

    The amended awk code replaces

    $NF = int(rand() * 100 + 800)
    

    with

    do {
      $NF = int(rand() * 100 + 800)
    } while(!seen[$NF]++)
    

    ...in other words, it keeps a table of random numbers it has already used and keeps drawing numbers until it gets one it hasn't seen before.

    0 讨论(0)
提交回复
热议问题