Awk 使用';sed';删除特定字符的换行符的步骤
我知道这个问题有过不同的提问和回答。但我的重点是为什么sed的行为不像我期望的那样 对于一个给定的threaddump文件,我需要在每一行“锁定可拥有的同步器”之前删除换行符,如下所示Awk 使用';sed';删除特定字符的换行符的步骤,awk,sed,Awk,Sed,我知道这个问题有过不同的提问和回答。但我的重点是为什么sed的行为不像我期望的那样 对于一个给定的threaddump文件,我需要在每一行“锁定可拥有的同步器”之前删除换行符,如下所示 at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awa
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at com.project.tools.threads.NamedThread.run(NamedThread.java:37)
Locked ownable synchronizers:
- None
我可以使用vi实现这一点:
:g/^M Locked ownable synchronizers/s// Locked ownable synchronizers/g
^^^^M是ctrl-M。上面的vi命令有效,即,它在锁定前成功删除换行符。然而,当我尝试在sed中使用它时,以下工作都没有完成(我尝试了多种方法来表示换行符,但都没有成功)
据我所知,vi命令在sed中工作(它们一直在工作)。为什么这个不管用
多谢各位
PS:有效的解决方案是使用perl:
perl -0pe 's/\n Locked ownable synchronizers:/ Locked ownable synchronizers:/g' < file.threaddump
perl-0pe的/\n锁定的可拥有同步器:/Locked ownable synchronizers:/g'
但我想弄明白为什么sed不起作用 首先,在vim中工作的一个更简单的
ex
命令是:
:%s/\n\( Locked\)/\1/
现在,用sed替换换行并不简单,因为sed逐行读取其输入,对于sed,一行本身不包含换行符(换行符只是行之间的分隔符)。因此,默认情况下,包含\n
的sed模式将不匹配任何内容
以前曾提出过用sed替换换行的问题,我们可以根据您的情况采用:
sed -e :a -e N -e '$!ba' -e 's/\n\( Locked\)/\1/' file.threaddump
对于这样一个简单的任务,上面的解决方案相当复杂,因为它试图让sed做一些它不打算做的事情,即匹配换行符 这个故事的寓意是:为工作选择正确的工具。 在这种情况下,更好的工具是允许重新定义记录分隔符的工具,以便换行符在字符串中显示为普通字符,而不被视为记录分隔符 Sed不允许这样做,因为它是专门为处理行而设计的,并且换行符被硬编码为记录分隔符 但是,正如您已经看到的,Perl允许使用
-0
开关执行此操作:
perl -0 -p -e 's/\n( Locked)/$1/' file.threaddump
-0
开关(不带参数)基本上将记录分隔符设置为空字符串,从而将整个输入视为单个记录。然后可以像s//
命令中的任何其他字符一样匹配换行符\n
注意:
如果您想删除回车符
\r
(U+000D)而不是换行符\n
(U+000A),您应该能够将上述代码中的\n
替换为\r
首先,在vim中工作的一个更简单的ex
命令是:
:%s/\n\( Locked\)/\1/
现在,用sed替换换行并不简单,因为sed逐行读取其输入,对于sed,一行本身不包含换行符(换行符只是行之间的分隔符)。因此,默认情况下,包含\n
的sed模式将不匹配任何内容
以前曾提出过用sed替换换行的问题,我们可以根据您的情况采用:
sed -e :a -e N -e '$!ba' -e 's/\n\( Locked\)/\1/' file.threaddump
对于这样一个简单的任务,上面的解决方案相当复杂,因为它试图让sed做一些它不打算做的事情,即匹配换行符 这个故事的寓意是:为工作选择正确的工具。 在这种情况下,更好的工具是允许重新定义记录分隔符的工具,以便换行符在字符串中显示为普通字符,而不被视为记录分隔符 Sed不允许这样做,因为它是专门为处理行而设计的,并且换行符被硬编码为记录分隔符 但是,正如您已经看到的,Perl允许使用
-0
开关执行此操作:
perl -0 -p -e 's/\n( Locked)/$1/' file.threaddump
-0
开关(不带参数)基本上将记录分隔符设置为空字符串,从而将整个输入视为单个记录。然后可以像s//
命令中的任何其他字符一样匹配换行符\n
注意:
如果您想删除回车符
\r
(U+000D)而不是换行符\n
(U+000A),您应该能够将上述代码中的\n
替换为\r
sed一次读取并操作一行。行由换行符分隔。因此,您不能从sed操作的行中删除换行符,因为它不包含换行符
由于sed仅用于单个行上的简单替换,因此您无论如何都应该使用awk:
awk -i inplace -v RS='^$' '{print gensub(/\n(\s*Locked ownable synchronizers)/,"\\1","g")}' file.threaddump
上面使用GNU awk而不是GNU sed进行就地编辑和其他语法分析。sed一次读取和操作一行。行由换行符分隔。因此,您不能从sed操作的行中删除换行符,因为它不包含换行符 由于sed仅用于单个行上的简单替换,因此您无论如何都应该使用awk:
awk -i inplace -v RS='^$' '{print gensub(/\n(\s*Locked ownable synchronizers)/,"\\1","g")}' file.threaddump
上面使用GNU awk而不是GNU sed进行就地编辑和其他语法调整。这可能适合您(GNU sed):
将第二行附加到第一行,如果该行以所需字符串开头,请删除前面的换行符并重复。否则,打印第一行,删除它并重复。这可能适合您(GNU-sed):
将第二行附加到第一行,如果该行以所需字符串开头,请删除前面的换行符并重复。否则打印第一行,删除并重复。您的解释很有道理,我对sed有了更好的理解。谢谢!你的解释有道理,我有更好的解释