awk - 使用 awk 如何使用新行字符重新打印找到的模式?

标签 awk design-patterns newline gsub

我有一个格式为的文本文件:

aaa: bcd;bcd;bcddd;aaa:bcd;bcd;bcd; 

其中“bcd”可以是任何长度的任何字符,不包括 ;:

我想要做的是打印以下格式的文本文件:

aaa: bcd;bcd;bcddd;
aaa: bcd;bcd;bcd;

-等-

我解决这个问题的方法是隔离“;...:”模式,然后重新打印该模式,而不使用初始的 ;

我得出的结论是,我必须使用 awk 的“gsub”来执行此操作,但不知道如何复制该模式,也不知道如何使用在我的模式中添加的新行字符 1 个字符来再次打印该模式。

这可能吗? 如果没有,您能指导我解决这个问题吗?

最佳答案

我们不能完全确定 aaabcd 部分的可变性;想必,每一个都可以是几乎任何东西。

您可能应该寻找:

  • 一系列一个或多个非冒号、非分号​​字符,后跟冒号,
  • 重复一次或多次:
    • 一系列一个或多个非冒号、非分号​​字符,后跟一个分号

这构成了您要匹配的单位。

/[^:;]+:([^:;]+;)+/

这样,您就可以将找到的内容替换为相同的内容,后跟换行符,然后打印结果。唯一的技巧是避免多余的换行符。

示例脚本:

{
echo "aaa: bcd;bcd;bcddd;aaa:bcd;bcd;bcd;" 
echo "aaz: xcd;ycd;bczdd;baa:bed;bid;bud;"
} |
awk '{ gsub(/[^:;]+:([^:;]+;)+/, "&\n"); sub(/\n+$/, ""); print }'

输出示例

aaa: bcd;bcd;bcddd;
aaa:bcd;bcd;bcd;
aaz: xcd;ycd;bczdd;
baa:bed;bid;bud;

解释评论中的问题:

Why does the regular expression not include the characters before a colon (which is what it's intended to do, but I don't understand why)? I don't understand what "breaks" or ends the regex.

正如我在顶部试图解释的那样,您正在寻找我们所说的“单词”,即既不是冒号也不是分号的字符序列。在正则表达式中,即 [^:;]+,表示一个或多个 (+) 否定字符类 — 一个或多个非冒号、非分号字符。

假设正则表达式中的空格并不重要。我们可以像这样分隔正则表达式:

    / [^:;]+ : ( [^:;]+ ; ) + /

当然,斜杠只是标记结束。第一个簇是一个单词;然后是一个冒号。然后是一个用括号括起来的组,末尾用 + 标记。这意味着该组的内容必须至少出现一次,并且可以出现任意多次。群里有什么?好吧,一个单词后面跟着一个分号。不必每次都是同一个单词,但那里必须有一个单词。如果某件事可以发生零次或多次,那么您当然可以使用 * 代替 +

正则表达式停止的关键是第一行中间的aaa:不包含后面跟分号的单词;它是一个单词,后跟一个冒号。因此,正则表达式必须在此之前停止,因为 aaa: 与该组不匹配。因此,gsub() 找到第一个序列,并用相同的材​​料和换行符替换该文本(当然,就是 "&\n")。然后,它(gsub())在替换 Material 结束后直接恢复搜索,并且 - 你瞧 - 有一个单词后面跟着冒号,还有一些单词后面跟着分号,所以有一个第二个匹配项将替换为其原始 Material 和换行符。

我认为 $0 必须在行尾包含换行符。因此,如果没有 sub() 删除尾随换行符,则 print (隐含带有换行符的 $0 )会生成一个空行,我没有不想在输出中出现,所以我删除了无关的换行符。 $0 末尾的换行符不会与 gsub() 匹配,因为它后面没有冒号或分号。

关于awk - 使用 awk 如何使用新行字符重新打印找到的模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9918232/

相关文章:

ruby - 如何将换行符插入字符数组

ios - MBProgressHUD 在多行中显示标签文本

java - Android 字符串中的回车符/换行符\n

linux - 在 Linux 中将第 n 个字符更改为随机字符

javascript - 切换器在 Javascript 中的实现

linux - 在 CSV 文件末尾添加空列

C++:这个模式有名字吗,可以改进吗?

c# - 保持用户联系的最佳设计/方式是什么?

awk - 在 awk 中计数

linux - 如何选择第二列和第三列不相等且不等于 0 或 1 的行?(使用 awk)