繁体   English   中英

在 bash 中替换任何单词开头和结尾的特定字符

[英]Replace a specific character at any word's begin and end in bash

仅当它与模式“space-[AZ]”或“[AZ]-space”匹配时,我才需要删除连字符“-”字符。 (假设所有字母都是大写,空格可以是空格或换行符)

样本.txt

I AM EMPTY-HANDED AND I- WA-
-ANT SOME COO- COOKIES

我希望输出是

I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES

我已经使用 sed 和 awk 以及 perl 四处寻找答案,但我只能找到与删除两个模式或特定字符串之间的所有字符有关的答案,而不是 [AZ] 和空格之间的特定字符。

谢谢堆!!

如果perl是您的选择,您会尝试以下操作吗:

perl -pe 's/(^|(?<=\s))-(?=[A-Z])//g; s/(?<=[A-Z])-((?=\s)|$)//g' sample.txt
  • (?<=\\s)是一个零宽度的后视断言,它匹配前导空格而不将其包含在匹配的子字符串中。
  • (?=[AZ])是一个零宽度先行断言,它匹配 A 和 Z 之间的尾随字符,而不将其包含在匹配的子字符串中。
  • 结果,只有与上述模式匹配的破折号字符才会从原始文本中删除。
  • 第二个语句s/..//g是第一个语句s/..//g翻转版本。

你能不能试试以下。

awk '{for(i=1;i<=NF;i++){if($i ~ /^-[a-zA-Z]+$|^[a-zA-Z]+-$/){sub(/-/,"",$i)}}} 1' Input_file

添加非单衬形式的溶液:

awk '
{
  for(i=1;i<=NF;i++){
    if($i ~ /^-[a-zA-Z]+$|^[a-zA-Z]+-$/){
      sub(/-/,"",$i)
    }
  }
}
1
'  Input_file

输出如下。

I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES

如果您可以为sed提供扩展正则表达式(通常使用-E-r选项),那么您可以将sed表达式缩短为:

sed -E 's/(^|\s)-(\w)/\1\2/g;s/(\w)-(\s|$)/\1\2/g' file

基本形式是sed -E 's/find1/replace1/g;s/find2/replace2/g' file ,也可以写成单独的表达式sed -E -e 's/find1/replace1/g' -e 's/find2/replace2/g' (您的选择)。

s/find1/replace1/g的详细信息是:

  • find1
    • (^|\\s)定位并捕获开头或空格,
    • 后跟'-'连字符,
    • 然后捕获下一个\\w (word-character);
  • replace1只是\\1\\2使用前两个反向引用重新插入两个捕获。

下一个替换表达式是类似的,除了现在您要查找的是连字符后跟一个空格或末尾。 所以你有了:

  • find2
    • \\w (字字符)的捕获,
    • 后跟连字符,
    • 后跟捕获后续空格或结尾(\\s|$) ,然后
  • replace2和以前一样,只是使用反向引用重新插入捕获的字符。

在每种情况下, g表示所有出现的全局替换。

注意: \\w单词字符还包括'_' (下划线),因此虽然您不太可能将连字符和下划线放在一起,但如果您这样做,则需要使用[A-Za-z]列表而不是\\w )

示例使用/输出

在你的情况下,输出是:

$ sed -E 's/(^|\s)-(\w)/\1\2/g;s/(\w)-(\s|$)/\1\2/g' file
I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES

仅当它与模式 'space-[AZ]' 或 '[AZ]-space' 匹配时,才删除连字符 '-' 字符。 假设所有字母都是大写,空格可以是空格或换行符

它的:

sed 's/\( \|^\)-\([A-Z]\)/\1\2/g; s/\([A-Z]\)-\( \|$\)/\1\2/g'
  • s - 替代
    • /
    • \\( \\|^\\) - 空格或行首
    • - - 连字符...
    • \\(AZ]\\) - 单个大写字符
    • /
    • \\1\\2 - \\1被第一个\\(...\\)替换。 所以它被一个空格或什么都代替。 \\2被找到的单个大写字符替换。 有效-被删除。
    • /
    • g全局应用正则表达式
  • ; - 将两个s命令分开
  • s
    • 和上面一样。 $表示行尾。
awk '{sub(/ -/,"");sub(/^-|-$/,"");sub(/- /," ")}1' file
I AM EMPTY-HANDED AND I WA
ANT SOME COO COOKIES

暂无
暂无

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

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