根据外部或内部单引号以不同方式替换空格

问题描述 投票:0回答:6

我的输入有一些字段

  • 用空格分隔,
  • 其他一些用引号引起来,也用空格分隔

这是一个输入示例:

active=1 'oldest active'=0s disabled=0 'function call'=0

我想更换:

  • |
  • 引号外的所有空格
  • 所有内部引号由
    _

输出将是:

active=1|'oldest_active'=0s|disabled=0|'function_call'=0

我尝试了在网上找到的

sed
perl
不同的解决方案,但没有达到我想要的效果。

regex perl awk sed quotes
6个回答
2
投票
$ s="active=1 'oldest active'=0s disabled=0 'function call'=0"
$ echo "$s" | perl -pe "s/'[^']*'(*SKIP)(*F)| /|/g; s/ /_/g"
active=1|'oldest_active'=0s|disabled=0|'function_call'=0

两步更换:

  • 首先,
    '[^']*'(*SKIP)(*F)
    将跳过
    '
    包围的所有图案,并用
    |
  • 替换剩余的空格
  • 其次,
    '
    内现在留下的空格将替换为
    _


替代解决方案:

$ echo "$s" | perl -pe "s/'[^']*'/$& =~ s| |_|gr/ge; s/ /|/g"
active=1|'oldest_active'=0s|disabled=0|'function_call'=0
  • 灵感来自这个答案
  • '[^']*'/$& =~ s| |_|gr/ge
    使用另一个替换命令替换匹配模式
    '[^']*'
    中的所有空格。
    e
    修饰符允许在替换部分使用命令而不是字符串
  • 剩余空间则由
    s/ /|/g
  • 处理


延伸阅读:


1
投票

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

sed -r ":a;s/^([^']*('[^ ']*')*[^']*'[^' ]*) /\1_/;ta;y/ /|/" file

这首先将引用字符串中的所有空格替换为

_
的空格,然后将剩余的空格转换为
|
的空格。


1
投票

@anubhava 的解决方案让人想起老式的 Perl 解决方案:

$ echo $s | perl -047 -pe "(\$.%2)?s/ /|/g:s/ /_/g;"
active=1|'oldest_active'=0s|disabled=0|'function_call'=0

用单引号 (047) 分隔行并根据偶数/奇数进行细分。


1
投票

使用 gnu awk

RS
,您可以使用这个简单的解决方案:

s="active=1 'oldest active'=0s disabled=0 'function call'=0"

awk -v RS="'[^']*'" '{gsub(/ /, "|"); ORS=RT} 1' <<< "$s"

active=1|'oldest active'=0s|disabled=0|'function call'=0

详情:

  • 使用
    -v RS="'[^']*'"
    它告诉
    awk
    记录分隔符是每个单引号文本,即
    '...'
  • 使用
    gsub(/ /, "|")
    将剩余空格 (引号外) 替换为
    |
  • 使用
    ORS=RT
    设置输出记录分隔符与
    v RS='...'
  • 中匹配的输入文本
  • 1
    输出每条记录

参考: 有效的AWK编程


0
投票

我们可以在循环内使用正则表达式。

$str = "active=1 'oldest active'=0s disabled=0 'function call'=0";
print "\nBEF: $str\n";
$str =~s#active=1 'oldest active'=0s disabled=0 'function call'=0# my $tmp=$&; $tmp=~s/\'([^\']*)\'/my $tes=$&; $tes=~s{ }{\_}g; ($tes)/ge; $tmp=~s/ /\|/g; ($tmp); #ge;
print "\nAFT: $str\n";

除此之外可能还会有一些捷径。


0
投票
$ awk -F\' '{OFS=FS; for (i=1;i<=NF;i++) gsub(/ /,(i%2?"|":"_"),$i)}1' file
active=1|'oldest_active'=0s|disabled=0|'function_call'=0
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.