我有一个看起来像这样的文件:
t2_this_is_some_output_80_pool
address 12.34.56.78
state down
address 13.34.56.78
state down
t2_this_is_a_different_output_80_pool
address 14.34.56.78
t2_this_is_another_output_80_pool
address 15.34.56.78
state up
我想输出它看起来像:
t2_this_is_some_output_80_pool address 12.34.56.78 state down
t2_this_is_some_output_80_pool address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool 15.34.56.78 state up
我一直在尝试使用BASH,awk和sed,但我所做的一切都无法为我提供所需的输出。
我尝试过的其中一件事:
如果行以=
开头,则用一个=替换开头的12个空格,然后追加到上一行cat file.txt | sed 's/ /=/' | sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
但那不起作用......
任何帮助都会受到极大的欢迎: - )
答案 0 :(得分:1)
以下是一个简单的选项,它结合了sed
反向引用和您的=
标识符:
sed -r 's/^([^ ])/=\1/g' file.txt |tr '\n' ' ' |tr '=' '\n' |sed -r 's/ +/ /g'
这会产生以下输出,如果我正确地得到您的问题,可能不会完全符合您的要求(因为它没有在相应的t2_
开始新的一行每个地址的开头):
t2_this_is_some_output_80_pool address 12.34.56.78 state down address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool address 15.34.56.78 state up
<强>解释强>
sed -r 's/^([^ ])/=\1/g'
:在每行的开头放一个=
字符,而不是以空格开头。输出:
=t2_this_is_some_output_80_pool
address 12.34.56.78
state down
address 13.34.56.78
state down
=t2_this_is_a_different_output_80_pool
address 14.34.56.78
=t2_this_is_another_output_80_pool
address 15.34.56.78
state up
tr '\n' ' '
:用空格字符替换每个换行符。输出:
=t2_this_is_some_output_80_pool address 12.34.56.78 state down address 13.34.56.78 state down =t2_this_is_a_different_output_80_pool address 14.34.56.78 =t2_this_is_another_output_80_pool address 15.34.56.78 state up
tr '=' '\n'
:用换行符替换每个=
个字符。输出:
t2_this_is_some_output_80_pool address 12.34.56.78 state down address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool address 15.34.56.78 state up
sed -r 's/ +/ /g'
:用一个空格字符替换所有连续空格字符。输出:
t2_this_is_some_output_80_pool address 12.34.56.78 state down address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool address 15.34.56.78 state up
答案 1 :(得分:1)
也许是这样:
$ cat f1
t2_this_is_some_output_80_pool
address 12.34.56.78
state down
address 13.34.56.78
state down
t2_this_is_a_different_output_80_pool
address 14.34.56.78
t2_this_is_another_output_80_pool
address 15.34.56.78
state up
$ echo $(cat f1) | sed 's/t2/\nt2/g'
t2_this_is_some_output_80_pool address 12.34.56.78 state down address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool address 15.34.56.78 state up
答案 2 :(得分:1)
sed ':a; $!N;s/\n[ ]\+/ /;ta;P;D' yourfile.txt
$!N
如果它不是最后一行,则附加下一行。
s\n[ ]\+/ /
用一个空格替换新行后的所有空格。
ta
如果匹配,请转到标签:a
P
打印修改后的行
D
删除旧版本的
答案 3 :(得分:0)
sed '
# for every new section (starting with non space)
/^[^[:blank:]]/ {
# copy it to the hold buffer
h
# delete the line (and go to next line)
d
}
# other line(s)
# add next line
N
# add holding buffer to current line (with new line between)
G
# reformat, removing new line followed by spaces and putitnging last line in front
s/[[:blank:]]*\([^[:blank:]].*\)\^J[[:blank:]]*\([^[:blank:]].*\)\^J\(.*\)/\3 \1 \2/
# print the resulting line
' YourFile
所以在线游戏POSIX
sed -e '/^[^[:blank:]]/{h;d' -e '};N;G;s/[[:blank:]]*\([^[:blank:]].*\)\^J[[:blank:]]*\([^[:blank:]].*\)\^J\(.*\)/\3 \1 \2/' YourFile
注意:\^J
是一个真正的新行CTRL + V + J. \n
可用于gawk和\
使用POSIX的新行等效
答案 4 :(得分:0)
我相信使用简单的awk脚本会更容易和更容易理解,例如:
awk '
BEGIN {
separator_address = "address" # Put what you want here
line=""
addr=""
args=""
}
{
if (substr($0, 1, 1) != " ") { # Start by a space
if (addr != "") {
print line" "addr" "args
}
line=$0
addr = ""
args = ""
next # Nothing more to do here
}
gsub(/^[ \t]+/,"",$0) # Remove spaces
if (substr($0, 1, length(separator_address)) == separator_address) {
if (addr == "") {
addr = $0
} else {
print line" "addr" "args
addr = $0
args = ""
}
} else {
args = $0
}
}
END {
if (addr != "") {
print line" "addr" "args
}
}' file.txt
Sed确实非常强大,但在多线治疗方面并不是很方便。 但由于我并不是真的想要分割线,我使用了一个分隔符(&#34;地址&#34;)。如果是两行,则可以使用标志而不是分隔符(初始化为0,如果读取以空格开头的值,则为+1,如果达到2则打印,例如,在每次打印后重新初始化)。 / p>
结果:
t2_this_is_some_output_80_pool address 12.34.56.78 state down
t2_this_is_some_output_80_pool address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool 15.34.56.78 state up
答案 5 :(得分:0)
awk '
/^[^[:blank:]+]/{ # search for record/line does not start with blank
if(s){print s; s=""} # This is whenever state not found then print variable s
p=$0 # store record in varibale p
next # stop processing go to next line
}
{
gsub(/^[ \t]+/,"") # suppress starting space/tab char
s = s ? s OFS $0: p OFS $0 # if variable s has something then concatenate variable s with current record else variable p and current record
}
/state/{ # if record has word state then
print s; s="" # print variable s and reset variable
}
END{ # end block
if(s)print s # if s has something print s
}' file
<强> Oneliner 强>
$ awk '/^[^[:blank:]+]/{if(s){print s; s=""}p=$0; next}{gsub(/^[ \t]+/,"");s = s ? s OFS $0: p OFS $0; }/state/{print s; s=""}END{if(s)print s}' file
<强>输入强>
$ cat f
t2_this_is_some_output_80_pool
address 12.34.56.78
state down
address 13.34.56.78
state down
t2_this_is_a_different_output_80_pool
address 14.34.56.78
t2_this_is_another_output_80_pool
address 15.34.56.78
state up
输出
$ awk '
/^[^[:blank:]+]/{
if(s){print s; s=""}
p=$0;
next
}
{
gsub(/^[ \t]+/,"")
s = s ? s OFS $0: p OFS $0
}
/state/{
print s; s=""
}
END{
if(s)print s
}' f
t2_this_is_some_output_80_pool address 12.34.56.78 state down
t2_this_is_some_output_80_pool address 13.34.56.78 state down
t2_this_is_a_different_output_80_pool address 14.34.56.78
t2_this_is_another_output_80_pool address 15.34.56.78 state up
答案 6 :(得分:0)
@try:还有一种方法。
awk '{ORS=$0 ~ /^ +/?"":RS} {$1=$1} 1; END{print RS}' Input_file
编辑:此处成功添加代码说明。
awk '{
ORS= ##### Setting ORS(Output record separator) here, where output field separator is awk's default keyword whose default value is a new line.
$0 ~ /^ +/ ##### Checking if any record/line is starting from space here.
? ##### Conditional operator here, which will execute it's following statements if above mentioned condition is TRUE.
"" ##### If above mentioned conditions is TRUE then setting ORS's value to NULL.
: ##### : is a conditional operator here, which will execute the statements following it when conditions is FALSE.
RS} ##### Setting ORS's value to RS(Record separator) whose default value will be a new line.
{$1=$1} ##### Resetting the $1(first field) here, so that value of ORS could be reflected here.
1; ##### Mentioning 1 here. awk works on condition then action method, so I am making condition TRUE here and not mentioning any action here so by default print action will happen here.
END{print RS} ##### in this block printing the RS(record separator)'s value here.
' Input_file ##### mentioning the Input_file here.
答案 7 :(得分:0)
如果你不介意在开头有一个额外的新行,而在最后没有,那么这个简短的脚本就可以了:
awk '/^[^ ]/ { printf "\n" } $1=$1' ORS=' '
您可以分别添加NR>1
和END { print "\n" }
来解决这两个问题。