用awk中的换行替换\n

Cot*_*ten 11 bash awk

我拖尾日志,他们输出\n而不是换行.

我想我应该管tailawk,做一个简单的替换,但我似乎无法逃脱正则表达式的换行符.在这里,我正在展示我的问题,cat而不是tail:

// test.txt
John\nDoe
Sara\nConnor

cat test.txt | awk -F'\\n' '{ print $1 "\n" $2 }'
Run Code Online (Sandbox Code Playgroud)

期望的输出:

John
Doe
Sara
Connor
Run Code Online (Sandbox Code Playgroud)

实际产量:

John\nDoe
        <-  there is a newline here
Sara\nConnor
        <-  there is a newline here     
Run Code Online (Sandbox Code Playgroud)

所以它看起来与test.txt中的名字和姓氏\\n不匹配,\n而是每行末尾的换行符.

它看起来\\n不是在终端中逃脱的正确方法吗?这种转义方式在Sublime Text中很好用:

正则表达式在ST3工作

Avi*_*Raj 23

这个怎么样?

$ cat file
John\nDoe
Sara\nConnor

$ awk '{gsub(/\\n/,"\n")}1' file
John
Doe
Sara
Connor
Run Code Online (Sandbox Code Playgroud)

  • op标记了awk标记. (7认同)
  • 你可以用 `RS` 改变 `"\n"` 并得到 `awk '{gsub(/\\n/,RS)}1'` (2认同)
  • 也许我不应该标记这个“awk”,但我做了,而且这个答案有效。但是“sed”似乎更适合这项任务?问题是 `sed` 在 Mac OSX 上表现得很奇怪,请参阅 @DarkDust 和 @Ed Morton 的答案。 (2认同)
  • @Cotten 我不会强迫你。寻求最适合您的任何其他解决方案。 (2认同)

AZA*_*med 8

我以前曾遇到过这个问题,但我发现最干净的方法是使用内置的printf

printf "$(cat file.txt)" | less
Run Code Online (Sandbox Code Playgroud)

这是一个处理 aws iam 在输出中嵌入 json 策略的真实示例,文件 file.txt 包含:

{
  "registryId": "111122223333",
  "repositoryName": "awesome-repo",
  "policyText": "{\n  \"Version\" : \"2008-10-17\",\n  \"Statement\" : [ {\n    \"Sid\" : \"AllowPushPull\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : [ \"arn:aws:iam::444455556666:root\", \"arn:aws:iam::444455556666:user/johndoe\" ]\n    },\n    \"Action\" : [ \"ecr:BatchCheckLayerAvailability\", \"ecr:BatchGetImage\", \"ecr:CompleteLayerUpload\", \"ecr:DescribeImages\", \"ecr:DescribeRepositories\", \"ecr:GetDownloadUrlForLayer\", \"ecr:InitiateLayerUpload\", \"ecr:PutImage\", \"ecr:UploadLayerPart\" ]\n  } ]\n}"
}
Run Code Online (Sandbox Code Playgroud)

应用上述内容(没有较少的内容)后,您将得到:

{
  "registryId": "111122223333",
  "repositoryName": "awesome-repo",
  "policyText": "{
  "Version" : "2008-10-17",
  "Statement" : [ {
    "Sid" : "AllowPushPull",
    "Effect" : "Allow",
    "Principal" : {
      "AWS" : [ "arn:aws:iam::444455556666:root", "arn:aws:iam::444455556666:user/johndoe" ]
    },
    "Action" : [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr:CompleteLayerUpload", "ecr:DescribeImages", "ecr:DescribeRepositories", "ecr:GetDownloadUrlForLayer", "ecr:InitiateLayerUpload", "ecr:PutImage", "ecr:UploadLayerPart" ]
  } ]
}"
}
Run Code Online (Sandbox Code Playgroud)

请注意,“policyText”的值本身就是一个包含 json 的字符串。


Dar*_*ust 7

使用GNU sed,解决方案非常简单,因为@ hek2mgl已经回答了(并且恕我直言,它应该在任何地方工作,但不幸的是没有).

但是在Mac OS X其他*BSD UNIX上执行此操作时有点棘手.

最好的方式是这样的:

sed 's/\\n/\'$'\n''/g' <<< 'ABC\n123'
Run Code Online (Sandbox Code Playgroud)

然后当然还有AWK,@ AvinashRaj有正确的答案,如果你想使用它.

  • 那么,让我们实际看一下[POSIX标准](http://pubs.opengroup.org/onlinepubs/009695399/utilities/sed.html):问题是标准没有指定`s`的第二部分( "替换")应解释`\n`或不解释.因为它不是BRE而且"\"在这里有特殊意义我会说它不应该.BSD sed的[POSIX备注](https://github.com/freebsd/freebsd/blob/master/usr.bin/sed/POSIX)表明历史版本没有并丢弃"\"(见第16点) .所以两者都是POSIX兼容的,因为标准没有指定行为. (2认同)
  • 是的,发生的事情是shell在sed尝试执行脚本之前正在评估`$'\n/g'`并且扩展为文字换行符后跟`/ g`,因此它通过共同发生"起作用".在shell将扩展的`/`之后它不适用于不同的字符--`/g`恰好是无害的. (2认同)

Ed *_*ton 7

这适用于任何系统上的任何sed,因为它是在sed中使用换行符的便携方式:

$ sed 's/\\n/\
/' file
John
Doe
Sara
Connor
Run Code Online (Sandbox Code Playgroud)

如果您输入的内容可能包含类似的行,foo\\nbar并且它\\是一个转义反斜杠,那么您就不能使用像您所要求的简单替换方法.


hek*_*mgl 5

我会用sed

sed 's/\\n/\n/g' file
Run Code Online (Sandbox Code Playgroud)

  • BSD 的 `sed` 没有 `--posix`,它已经符合 POSIX 标准。GNU 的 `sed` 对 POSIX 有很多(有用的)扩展,而 `--posix` 应该禁用它们。我找到了一个[答案,提供了适用于所有系统的解决方案](http://stackoverflow.com/a/19883696/400056)(在Mac和Linux上测试)。 (2认同)

use*_*558 5

为什么要使用两种awksed此?使用perl

perl -pe 's/\\n/\n/g' file
Run Code Online (Sandbox Code Playgroud)

通过使用它,perl您不必考虑posix合规性,它通常可以提供更好的性能,并且在所有(大多数)平台上都可以保持一致。