我已经向以下方面发出了答复......请找到它。如果您可以,请随意优化它。)。
所以问题的简要描述:我已经创建了一个带有来自psql查询的大量输出的文件,我试图使用这些数据,但输出的格式并不理想。以下是数据的细分:
some_date | some_username | some_port | 声明:
:选择some_query
some_date | some_username | some_port |声明:SELECT some_different_query
这就是数据的样子,问题是粗线。我不知道为什么这句话被分成两行,但它与我需要做的其余处理相混淆。如果我只看粗体部分的字符,它的含义如下:
声明产品:> $
产品:>查询$
>
是空格,$
是eol字符。
所以我真的需要将这两行加在一起,但我不知道如何。这是我到目前为止所尝试的:
sed 's/\n://g' filename
显然,这不起作用。也有道理,因为我相信SED在线到线的基础上工作。任何建议都将很高兴。
以下是数据的屏幕截图。我无法复制数据,因为我的VM无法允许它。遗憾...
以下是我希望看到这些数据的方式...尝试使用你的awk:P:
答案 0 :(得分:2)
sed用于单个行上的简单替换,即全部。对于任何更有趣的事情,你应该使用awk来实现清晰,简洁,健壮,可移植性以及几乎所有其他理想的软件属性。
鉴于我编写的这个示例输入文件:
$ cat file
some_date | some_username | some_port | statement:
: SELECT some_query
:lines and lines
:of stuff...
some_date | some_username | some_port | statement: SELECT some_different_query
some_date | some_username | some_port | statement:
: SELECT something else where
:the quick brown fox
: jumped over
: the lazy
:dog's back
这个awk命令可能就是你想要的:
$ awk '{printf "%s%s", (NR==1 || sub(/^: */,OFS) ? "" : ORS), $0} END{print ""}' file
some_date | some_username | some_port | statement: SELECT some_query lines and lines of stuff...
some_date | some_username | some_port | statement: SELECT some_different_query
some_date | some_username | some_port | statement: SELECT something else where the quick brown fox jumped over the lazy dog's back
但是我必须自己编写输入集以进行测试,因此它可能与您的实际输入不匹配,而且您没有发布任何预期的输出,所以我只是猜测。
如果没有,请编辑您的问题,以提供几行具体,可测试的样本输入和预期输出。
如果您不熟悉awk和其他类C语言,请参阅awk命令的含义:
awk '
{ # WHILE read the current line ($0) DO
printf "%s%s", # prepare to print 2 strings with no trailing newline
(NR==1 # IF this is the first line of input
|| sub(/^: */,OFS) # OR we can replace :<space>* with one space (OFS)
? # THEN
"" # the first string to print is NULL
: # ELSE
ORS # the first string to print is a newline (ORS)
) # ENDIF
, $0 # the second string to print is the current input line
} # ENDWHILE
END{print ""} # print a newline (ORS) at the end of the output
' file
该部分被注释为IF..ENDIF只是许多语言中使用的常见三元表达式,OFS和ORS是awk内置变量而不是包含输出字段分隔符和输出记录分隔符字符串(默认情况下是单个空格和换行符。)
答案 1 :(得分:1)
sed -e ':a' -e '/: $/{s///;N;s/\n: //;ba' -e '}' YourFile
尝试重新组合以切割分隔符结尾的行(并将其删除)
N
将新行加载到当前缓冲区,因此您可以使用多行并将换行视为普通字符
使用新信息,其中有1行以:
结尾,后面跟着说明
`:\但不以先前的分隔符结尾
sed -e 's/: $//;1h;1!H;$!d' -e 'x;s/\n: //g' YourFile
答案 2 :(得分:0)
所以它不漂亮,但我找到了答案:)。可能有一些方法可以缩短这条线,我很欣赏任何关于如何做的回应,我喜欢学习新的做事方式。这就是答案:
sed ':x; /\:$/ { N; s/\:\n//; tx }' temp.txt | sed ':x; /\, $/ { N; s/\n\://; tx }' | sed ':x; /.\([a-zA-Z0-9]*\)$/ { N; s/\n\://; tx }'
希望我没有复制错误。一个简短的解释,适用于任何想要使用类似实例的人。第一部分查找以:
结尾的所有行,并替换换行符和下一行的第一个:
。第二部分查找以,
结尾的所有行,并替换那里的换行符和下一行的:
。最后一部分查找以任何正常字符或数字结尾的所有行(因此[a-zA-Z0-9]
)并删除换行符以及下一行的:
。
复杂(对我来说至少:)),但很有趣。
感谢所有回复。
已编辑2015-09-22
我设法将这个可怕的长期命令发送到一个'更简单'的一个班轮:
sed -e ':loop' -e ':x; /.\([a-zA-Z0-9]*\)$/ { N; s/\n\://; tx }' -e 'b loop'
适用于我迄今为止发现的每一个案例:)。我标记为答案的awk答案仍然是最简单的。
-Ryan
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed 'N;s/:\n:/:/;P;D' file
或者如果该行被分成多行:
sed ':a;N;s/:\n:/:/;ta;P;D' file