简体   繁体   English

Shell脚本,使用sed替换字符

[英]Shell scripting, replace the characters using sed

In shell scripting, i want to replace 1bc1034gf45dna22 (16 characters total) with 1b:c1:03:4g:f4:5d:na:22 (seperated by colon) using sed. 在shell脚本中,我想使用1bc1034gf45dna221bc1034gf45dna22 (总共16个字符)替换为1b:c1:03:4g:f4:5d:na:22 (由冒号分隔)。

Edit 编辑

I have tried 我努力了

sed 's/\w{2}/\w{2}:/g' a.txt > b.txt

where a.txt has a.txt在哪里

1bc1034gf45dna22

Too Many Edge Cases 边缘案例过多

Sed is not an ideal tool for this job, because there are just too many edge cases. Sed并不是理想的工具,因为边缘情况太多了。 If you have very regular data and a known corpus then that's fine, but in some cases you need something more powerful that can act on pieces of a line independently after matching/capturing the text of interest. 如果你有非常常规数据和已知的语料库那么这很好,但在某些情况下,你需要更强大的东西,可以匹配后独立一行 ACT /捕获感兴趣的文本。 For example, given an input file containing: 例如,给定一个包含以下内容的输入文件:

foo 1bc1034gf45dna22 bar

you might need to extract the second column, transform it, and then substitute it in place. 您可能需要提取第二列,对其进行转换,然后将其替换为适当位置。 You might do this with Ruby as follows: 您可以使用Ruby进行以下操作:

$ echo 'foo 1bc1034gf45dna22 bar' |
ruby -pe '
  if /(?<str>\p{Alnum}{16})/ =~ $_
    $_.sub!(str, str.scan(/../).join(?:))
  end'

This correctly yields: 正确地产生:

foo 1b:c1:03:4g:f4:5d:na:22 bar

这可能对您有用(GNU sed):

sed 's/\w\w\B/&:/g' file

Does 是否

sed -e 's/../&:/g' -e 's/:$//' a.txt > b.txt

or 要么

sed -e 's/\(..\)/\1:/g' -e 's/:$//' a.txt > b.txt

work for you? 为你工作?

为什么不sed 's/1bc1034gf45dna22/1b:c1:03:4g:f4:5d:na:2/g' file

With GNU/sed on any GNU/Linux distro you can use extentded regular expressions. 在任何GNU / Linux发行版上使用GNU / sed,您都可以使用扩展正则表达式。 This will convert a string of any length to a string where each two letters are separated by a colon: 这会将任意长度的字符串转换为字符串,其中两个字母之间用冒号分隔:

echo 1bc1034gf45dna22 | sed -re 's/(\w{2})/\1:/g' -e 's/:$//'

On your AIX platform, you can leverage awk: 在您的AIX平台上,您可以利用awk:

echo 1bc1034gf45dna22 | awk '
  BEGIN { FS=""; ORS=""; } 
  {
    for (i=1; i <=NF; i++) {
      if (i > 1 && (i + 1) % 2 == 0) { 
        print(":"); 
      }  

      print($i);
    }
  }'

You could: 你可以:

sed -i 's/\(\w\{2\}\)/\1:/g' file

This would also append a : to the end of the string. 这还将在字符串的末尾附加一个:。 Since we cannot use positive lookahead in our sed regex syntax, we would then need to: 由于我们不能在sed regex语法中使用正向超前,因此我们需要:

sed -i 's/:$//g' file

Notice that we used inplace editing for sed therefore the file will in this way altered. 请注意,我们对sed使用了就地编辑,因此文件将以这种方式更改。

Alternatively, you could use perl to use a regex that would have been /(\\w{2})(?=\\w{2})/$1:/g 或者,您可以使用perl来使用原本为/(\\ w {2})(?= \\ w {2})/ $ 1:/ g的正则表达式

Well, there's always the brute-force method: 好吧,总有蛮力方法:

sed 's/\<'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\([0-9a-z][0-9a-z]\)'\
'\>/\1:\2:\3:\4:\5:\6:\7:\8/g'

With no leading spaces on the continuation lines the shell pastes the strings together properly. 连续线上没有前导空格,外壳将字符串正确粘贴在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM