Regex 如何在线的匹配部分内执行sed变换
在与特定模式匹配的直线内进行sed变换很容易,但如果我们只想变换直线的特定部分,该怎么办 简单例子 假设我们要使所有以Regex 如何在线的匹配部分内执行sed变换,regex,bash,awk,replace,sed,Regex,Bash,Awk,Replace,Sed,在与特定模式匹配的直线内进行sed变换很容易,但如果我们只想变换直线的特定部分,该怎么办 简单例子 假设我们要使所有以#开头的行中的所有字符都大写。我们可以通过以下形式的命令来实现这一点 sed '/^#/ y/abcdef/ABCDEF/' 假设我们只想把这些行中的第一个单词变成大写。我们将如何使用sed翻译 更高级的应用程序 我想在git的输出的图形部分用反斜杠交换斜杠--无寻呼机日志--全部--图形--装饰--单线--颜色=始终| tac 以前 之后 请注意,提交消息中的任何斜杠都保持不
#
开头的行中的所有字符都大写。我们可以通过以下形式的命令来实现这一点
sed '/^#/ y/abcdef/ABCDEF/'
假设我们只想把这些行中的第一个单词变成大写。我们将如何使用sed翻译
更高级的应用程序
我想在git的输出的图形部分用反斜杠交换斜杠--无寻呼机日志--全部--图形--装饰--单线--颜色=始终| tac
以前
之后
请注意,提交消息中的任何斜杠都保持不变,但图形部分中的斜杠会被转换。如果您的sed版本支持它,您可以使用
\U
将文本转换为大写:
sed -r 's/(^# *)([^ ]*)/\1\U\2/'
这将捕获以#
开头的任何行的第一部分(包括可选空格),然后是直到下一个空格字符的任何内容。第二个捕获组被转换为大写
如果它不支持,则始终可以使用perl:
perl -pe 's/(^#\s*)([\S]*)/$1\U$2/'
我在这个版本中使用了\s
和\s
,它们分别相当于[[:space:]
(空格字符)和[^[:space:]
(非空格字符)。您可能希望使用稍微不同的模式,具体取决于您正在处理的文件的具体情况。这可能适合您(GNU-sed):
或:
保持简单,只需使用awk。e、 g.第三个参数要匹配的GNU awk() 添加任何awk和注释,以防脚本的功能不明显:
$ cat tst.awk
{
match($0,/[| *\/\\]+/) # find the segment of text you want
tgt = substr($0,RSTART,RLENGTH) # save that segment in a variable tgt
gsub(/\//,RS,tgt) # change all /s to newlines in tgt
gsub(/\\/,"/",tgt) # change all \s to /s in tgt
gsub(RS,"\\",tgt) # change all newlines to \s in tgt
print tgt substr($0,RSTART+RLENGTH) # print tgt plus rest of the line
}
我们在字符交换期间使用换行符作为tmp值,因为保证换行符中不会出现换行符
顺便说一句,要将以#
开头的每行的第一个单词改为大写,可以是:
awk '/^#/{$1=toupper($1)}1' file
或:
根据您的输入数据、单词的定义和空格要求
如果您想要匹配的文本可以包含控制字符,就像您的注释中所说的那样,那么只需在regexp中允许它,例如:
match($0,/([[:space:][:cntrl:]|*\/\\]+)(.*)/,a)
这里有一个简单的sed解决方案,它应该是可移植的(即在GNU以外的sed变体中工作)。这将交换不跟随字母的斜杠(至少在示例数据中有效)
这方面的细分有点像这样:
s:\([^a-z]\)/:\1\\:g
-用反斜杠替换正斜杠
t
-如果我们只是做了一次替换,请跳到末尾(避免下一次替换)
s:\([^a-z]\)\:\1/:g
-将反斜杠替换为正斜杠
将其拆分为两个-e
表达式的原因是sed的一些变体要求分支名称位于脚本中的一行末尾。-e
表达式的结尾被视为等同于行的结尾。向我们展示一个输入和所需输出的示例会更有用。您介意解释后一个复杂表达式的作用吗?向我们展示该命令的输出示例,以及您希望将其转换为的内容。我不清楚它与您的原始需求有何关系。我注意到在您的示例中,origin/DR-01
已更改为origin\DR-01
——这是有意的吗?顺便说一句,我认为你应该摆脱你原来的例子,把重点放在与你的git输出相关的特定问题上,因为这会让你的问题更清楚。所以,给我们展示你想要的,否则有人会给你一个同样的答案!命令git--no-pager log--all--graph--decoration--oneline--color=always | tac | sed-e's:\([^a-z]\)/:\1\:g;t'-e's:\([^a-z]\)\:\1/:g'
似乎不起作用。斜杠没有被碰。@chieltenbrink-切换到--color=never
,它就工作了。散落在不同颜色字符之间的ANSI/vt100/xterm代码妨碍了sed对该行的解释。要查看真正发生的情况,请尝试查看通过cat-et
传输的git
命令的转储。当颜色设置为^[[33m
,sed看到的是m
。如果您可以选择不使用颜色,我的答案中的sed脚本将起作用。如果没有,则需要更复杂的内容。添加这样的量词似乎有效:git--no-pager log--all--graph--decoration--oneline--color=always | tac | sed-e's:\([^a-z]*\)/:\1\:g;t'-e's:\([^a-z]*\)\:\1/:g'
。如果允许在(背面)前“零个或多个非字母”斜杠,您允许将origin/DR-01
转换为origin\DR-01
。这不是解决办法。这似乎不适用于标记--color=always
。我不知道这意味着什么,awk没有--color=always
标记。如果您有一些上面不适用的输入集,请将您的问题编辑为显示该输入和预期输出。该脚本适用于发布的示例输入或任何以空格、/、\、|和/或*字符序列开头的其他字符。哦,我从另一个答案下的注释中看到,您正在运行一些命令,将控制字符注入文本中-只需将括号表达式中的``更改为includee控制字符(例如,^[:打印:
)脚本会运行的。谢谢!记录在案,OP包括我正在尝试处理命令git--no pager log--all--graph--decoration--oneline--color=always | tac
。是的,它会运行。但是对于那些没有git
并且对它的输出一无所知的人,我们所要做的就是你输入的示例在你的问题中提供,我们倾向于忽略你所说的任何命令
sed '/^#/!b;s/\w\w*/&\n/;h;y/abcdef/ABCDEF/;G;s/\n.*\n//' file
$ cat tst.awk
{
match($0,/([| *\/\\]+)(.*)/,a)
gsub(/\//,RS,a[1])
gsub(/\\/,"/",a[1])
gsub(RS,"\\",a[1])
print a[1] a[2]
}
$ awk -f tst.awk file
| * | | 279e9ad (tag: v0.0.4.334, origin/DR) asdfasdf
| | |\ \
| |\| \ \
| | |\ \ \
| | |/ / /
| | * | | 1fc7ab7 (tag: v0.0.4.337) Merge branch 'DR' into NextMajor
| | | * | d24e21d (tag: v0.0.4.341, origin/DR-01) DR-010728 Updated unit tests
| | |/ /
| | * | 8c01099 (tag: v0.0.4.338, tag: 0.0.4_MILESTONE_RELEASE) Merge
$ cat tst.awk
{
match($0,/[| *\/\\]+/) # find the segment of text you want
tgt = substr($0,RSTART,RLENGTH) # save that segment in a variable tgt
gsub(/\//,RS,tgt) # change all /s to newlines in tgt
gsub(/\\/,"/",tgt) # change all \s to /s in tgt
gsub(RS,"\\",tgt) # change all newlines to \s in tgt
print tgt substr($0,RSTART+RLENGTH) # print tgt plus rest of the line
}
awk '/^#/{$1=toupper($1)}1' file
awk '/^#/{$2=toupper($2)}1' file
match($0,/([[:space:][:cntrl:]|*\/\\]+)(.*)/,a)
sed -e 's:\([^a-z]\)/:\1\\:g;t' -e 's:\([^a-z]\)\\:\1/:g' file