Linux 用sed分隔文本文件

Linux 用sed分隔文本文件,linux,bash,sed,Linux,Bash,Sed,我有以下示例文件: evtlog.161202.002609.debugevtlog.161201.162408.debugevtlog.161202.011046.debugevtlog.161202.002809.debugevtlog.161201.160035.debugevtlog.161201.155140.debugevtlog.161201.232156.debugevtlog.161201.145017.debugevtlog.161201.154816.debug 我想在匹

我有以下示例文件:

evtlog.161202.002609.debugevtlog.161201.162408.debugevtlog.161202.011046.debugevtlog.161202.002809.debugevtlog.161201.160035.debugevtlog.161201.155140.debugevtlog.161201.232156.debugevtlog.161201.145017.debugevtlog.161201.154816.debug
我想在匹配“debug”后分离字符串并添加一个换行符,如下所示:

evtlog.161202.002609.debug
evtlog.161201.162408.debug
到目前为止,我几乎尝试了sed的所有功能,但它似乎不能满足我的需要

sed  's/debug/{G}' latest_evtlogs.out
sed  '/debug/i "SAD"' latest_evtlogs.out
等等。。。
sed's/debug/\n/g'latest\u evtlogs.out
在我将其作为管道添加到脚本中时不起作用,但在我手动运行它时起作用

以下是我生成文件的方式:

printf $(ls -l $EVTLOG_PATH/evtlog|tail -n 10|awk  '{printf $8 , "%s\n\n"}'|sed 's/debug/\n/g') >> latest_evtlogs.out
最初我想用awk添加新行,但它也不起作用。 你知道为什么我不能用换行符来分隔字符串吗

我正在使用:

Distributor ID: Debian
Description:    Debian GNU/Linux 5.0.10 (lenny)
Release:        5.0.10
Codename:       lenny

只需在调试后添加新行即可:

sed 's/debug/&\n/g' file
注意
&
打印回匹配的文本,因此这是一种将“调试”打印回的方法

这将返回:

evtlog.161202.002609.debug
evtlog.161201.162408.debug
evtlog.161202.011046.debug
evtlog.161202.002809.debug
evtlog.161201.160035.debug
evtlog.161201.155140.debug
evtlog.161201.232156.debug
evtlog.161201.145017.debug
evtlog.161201.154816.debug

在您的系统上,Perl可能比sed更“快乐”:

perl -pe 's/debug/&\n/g' < YourLogFile
perl-pe's/debug/&\n/g'
G
et会将保留缓冲区中的内容附加到模式空间(通常只是从输入文件读取的当前行),因此无法使用

i
nsert将指定文本打印到标准输出。所以这个不能用

要用
debug^J
替换所有
debug
,其中
^J
是新行,取决于sed版本,您可以执行以下操作之一:

sed 's/debug/&\n/g' input_file
但是
\n
在POSIX sed中没有严格指定-afaik。但是,可以使用c字符串:

sed 's/debug/&'$'\n''/g' input_file
或多行字符串:

sed 's/debug/&\
/g' input_file

问题是,您正在命令扩展中使用
sed
的输出。在此上下文中,shell将用空格替换所有换行符。然后使用空格进行分词,以便
printf
将每一行视为一个单独的参数,将第一行解释为format参数,并忽略其余行,因为格式中有
printf
-占位符

如果您从命令中删除外部的
printf$()
,并将输出从管道重定向到文件,则应该可以工作:

ls -l $EVTLOG_PATH/evtlog|tail -n 10|awk  '{printf $8 , "%s\n\n"}'|sed 's/debug/\n/g' >> latest_evtlogs.out

谢谢大家的回答。我终于这样做了:

echo $(ls -l $EVTLOG_PATH/evtlog|tail -n 10|awk  '{printf $8 , "%s\n\n"}'|sed 's/debug/&\n/g')  > temp.out

sed 's/ /\n/g' /share/sqa/dumps/5314577631/checks/temp.out > latest_evtlogs.out

它一点也不优雅,但终于可以工作了。

你确定你没有做很多不需要的处理吗?您使用
ls-l
获取目录的完整列表,然后使用Awk仅提取文件名并打印它而不使用换行符,然后尝试添加回换行符。为什么更简单的“script”
ls$EVTLOG_PATH/EVTLOG | tail-n 10>>最新的_evtlogs.out
不做你想做的事?@K.A Buhr,我尝试了它,它再次返回一个字符串。用于生成输出文件的
awk
命令不正确。格式字符串应该是第一个参数:
awk'{printf“%s\n\n”,$8}'
。正如@K.A.Buhr所建议的,最好使用
ls
而不是
ls-l
,因为这样就不需要使用
awk
。也许您实际上使用的是
somevar=$(long_命令);echo$somevar
。在本例中,请尝试
somevar=$(long\u命令);echo“$somevar”
。不,我仍然得到相同的结果:evtlog.161202.052817.debugevtlog.161201.212509.debugevtlog.161202.061126.debugevtlog.161202.062853.debugevtlog.161201.210226.debugevtlog.161201.205214.debugevtlog.161202.043057.debugevtlog.161201.205053.debugevtlog.161201.204846.debugevtlog.161201.211047.debugevtlog.161201.20532.debugevtlog.161201.2055217.debugevtlog.161202.043335.debugevtlog.161202.045555。debug@VeselinIvanov抱歉,在评论中,我们无法理解此类输出。最好更新您的问题指示器您的目标是什么,因为它看起来像是长管道的一部分抱歉,它看起来不可读。我的意思是它仍然是一个字符串,输出没有变化。@VeselinIvanov基本上,我会按照您在问题中得到的注释:只使用
ls
tail
,因为像现在这样解析ls的输出是非常脆弱的