在unix中用sed反转四个长度的字母

Posted

技术标签:

【中文标题】在unix中用sed反转四个长度的字母【英文标题】:Reverse four length of letters with sed in unix 【发布时间】:2018-04-02 21:01:01 【问题描述】:

如何用sed 反转四个长度的字母?

例如:

the year was 1815.

转为:

the raey was 5181.

这是我的尝试:

cat filename | sed's/\([a-z]*\) *\([a-z]*\)/\2, \1/'

但它并没有按我的预期工作。

【问题讨论】:

单词由哪些字符组成?字母(小写/大写?)、数字?、下划线(例如:ab_c)等...你有 GNU sed 或其他版本吗? 在我的情况下,单词由小写字母、大写字母和数字组成。 我在 Ubuntu (cloud 9) 中有 GNU sed 【参考方案1】:

不确定是否可以在所有情况下使用 GNU sed。如果_ 没有出现在四个字母单词之前/之后,您可以使用

sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'

\b 是单词边界,单词定义是任何字母或数字或下划线字符。所以\b 将确保只匹配整个单词而不是单词的一部分

$ echo 'the year was 1815.' | sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'
the raey was 5181.
$ echo 'two time five three six good' | sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'
two emit evif three six doog

$ # but won't work if there are underscores around the words
$ echo '_good food' | sed -E 's/\b([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])\b/\4\3\2\1/gi'
_good doof

具有环视支持的工具适用于所有情况

$ echo '_good food' | perl -pe 's/(?<![a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])([a-z0-9])(?!=[a-z0-9])/$4$3$2$1/gi'
_doog doof

(?&lt;![a-z0-9])(?!=[a-z0-9]) 分别为负向后瞻和负前瞻

可以缩短为

perl -pe 's/(?<![a-z0-9])[a-z0-9]4(?!=[a-z0-9])/reverse $&/gie'

它使用e 修饰符将Perl 代码放在替换部分。这种形式适合轻松改变要反转的单词长度

【讨论】:

你能解释一下/'gi'中的'i'是什么吗?而且我不必担心_所以不用担心。 i 用于不区分大小写的匹配,否则需要[a-zA-Z0-9] 即使它在 4 个字母长度内也会失败。请与_123 核对,也许您不认为_ 作为字母之一? 是的,OP 在 cmets 中提到 Word is constitute of lower case letters, upper case letters and numbers in my case... 所以我的代码不会改变像 _1231;2a 这样的词,而你的会【参考方案2】:

即使四个长度的字母包含_s,也可能是最短的sed解决方案。

sed -r 's/\<(.)(.)(.)(.)\>/\4\3\2\1/g'

【讨论】:

【参考方案3】:

遵循 awk 可能会对您有所帮助。在 GNU awk 中对此进行了测试,并且仅使用提供的示例 Input_file

echo "the year was 1815." |
awk '
function reverse(val)
  num=split(val, array,"");
  i=array[num]=="."?num-1:num;
  for(;i>q;i--)
    var=var?var array[i]:array[i]
;
  printf (array[num]=="."?var".":var);
  var=""


for(j=1;j<=NF;j++)
  printf("%s%s",j==NF||j==2?reverse($j):$j,j==NF?RS:FS)
'

【讨论】:

awk 似乎比 sed 更有效。但是在 sed 中可以吗? @Dante,可以在sed 完成,对不起,我不是 sed 专家,也许你可以等待人们在 sed 中提供解决方案。【参考方案4】:

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

sed -r '/\<\w4\>/!b;s//\n&\n/g;s/^[^\n]/\n&/;:a;/\n\n/!s/(.*\n)([^\n])(.*\n)/\2\1\3/;ta;s/^([^\n]*)(.*)\n\n/\2\1/;ta;s/\n//' file

如果没有反转所需长度的字符串,则退出。

在所有必需的字符串前面加上换行符。

在模式空间 (PS) 的开头插入换行符。 PS分为两部分,第一行将包含当前正在反转的单词。其余部分将包含原始行。

要反转的单词的每个字符都插入到第一行的前面并从原始行中删除。当单词中的所有字符都被处理后,原来的单词就会消失,只存在边界换行符。然后将这些双换行符替换为第一行中的单词,并重复该过程,直到处理完所有单词。最后引入换行符来分隔工作行和原来的行被移除并打印PS。

注意此方法可用于反转可变字符串长度的字符串,即通过更改任何数字的第一个正则表达式字符串可以反转。两个长度之间的字符串也可以反转,例如/\&lt;w2,4\&gt;/ 将更改 2 到 4 个字符长度之间的所有单词。

【讨论】:

【参考方案5】:

这是一个经常出现的问题,所以有人创建了一个名为“rev”的 bash 命令。

echo "$(echo the | rev) $(echo year | rev) $(echo was | rev) $(echo 1815 | rev)"。

回显“那一年是 1815 年。” |转 | tr ' ' '\n' |塔克 | tr '\n' ' '

【讨论】:

以上是关于在unix中用sed反转四个长度的字母的主要内容,如果未能解决你的问题,请参考以下文章

句子反转

句子反转

在python中用熊猫反转特殊字符

541-反转字符串 II

541-反转字符串 II

一行Java代码搞定字符串反转