Linux sed 将行连接在一起

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7852132/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 06:47:31  来源:igfitidea点击:

sed join lines together

regexlinuxsed

提问by veilig

what would be the sed (or other tool) command to join lines together in a file that do not end w/ the character '0'?

在不以字符“0”结尾的文件中将行连接在一起的 sed(或其他工具)命令是什么?

I'll have lines like this

我会有这样的线条

412|n|Leader Building Material||||||||||d|d|20||0

412|n|领先建筑材料|||||||||d|d|20||0

which need to be left alone, and then I'll have lines like this for example (which is 3 lines, but only one ends w/ 0)

需要单独留下,然后我会有这样的行(例如 3 行,但只有 1 行以 0 结尾)

107|n|Knot Tying Tools|||||Knot Tying Tools

|||||d|d|0||0

107|n|打结工具|||||打结工具

|||||d|d|0||0

which need to be joined/combined into one line

需要加入/组合成一行

107|n|Knot Tying Tools|||||Knot Tying Tools|||||d|d|0||0

107|n|打结工具|||||打结工具|||||d|d|0||0

采纳答案by ninjalj

 sed ':a;/0$/{N;s/\n//;ba}'

In a loop (branch bato label :a), if the current line ends in 0 (/0$/) append next line (N) and remove inner newline (s/\n//).

在循环中(分支ba到 label :a),如果当前行以 0 ( /0$/)结尾,则追加下一行 ( N) 并删除内部换行符 ( s/\n//)。

awk:

awk:

awk '{while(/0$/) { getline a; 
perl -pe '$_.=<>,s/\n// while /0$/'
=
while read line; do 
    if [ ${line: -1:1} != "0" ] ; then 
        echo $line
    else echo -n $line
fi
done 
a; sub(/\n/,_) }; print}'

Perl:

珀尔:

sed '/0$/!N;s/\n//'

bash:

重击:

perl -pe 'BEGIN{$/="0\n"}s/\n//g;$_.=$/'

回答by Karoly Horvath

if ends with 0 store, remove newline..

如果以 0 存储结尾,则删除换行符..

awk -F \| '
    NF == 17 {print; next}
    prev {print prev 
awk '!/0$/{printf 
kent$  cat t
#aasdfasdf
#asbbb0
#asf
#asdf0
#xxxxxx
#bar

kent$  awk '!/0$/{printf 
sed ':a;/0$/{N;s/\n//;ba}'
 does
 no one
 ie. 0
 people,
 try
 nothing,

 ie. 0
 things,
 any more,
 ie. 0
 tests?

          (^D aka eot 004 ctrl-D ?  ... bash generate via: echo ^V^D)
}/0$/' t #aasdfasdf#asbbb0 #asf#asdf0 #xxxxxx#bar
}/0$/'
; prev = ""} {prev =
 does no one ie. 0
 people, try nothing, ie. 0
 things, any more, ie. 0
 tests?          (^D aka eot 004 ctrl-D ?  ... bash generate via: echo ^V^D)
} '

回答by glenn Hymanman

A typically cryptic Perl one-liner:

一个典型的神秘 Perl 单行:

sed 'H;${z;x;s/\n//g;p;};/0$/!d;z;x;s/\n//g;'

This uses the sequence "0\n" as the record separator (by your question, I'm assuming that every line should end with a zero). Any record then should not have internal newlines, so those are removed, then print the line, appending the 0 and newline that were removed.

这使用序列“0\n”作为记录分隔符(根据您的问题,我假设每一行都应以零结尾)。任何记录都不应该有内部换行符,所以这些被删除,然后打印该行,附加被删除的 0 和换行符。

Another take to your question would be to ensure each line has 17 pipe-separated fields. This does not assume that the 17th field value must be zero.

另一个问题是确保每行都有 17 个管道分隔的字段。这并不假设第 17 个字段值必须为零。

sed ':a;/0$/!{N;s/\n//;ba}'

回答by Kent

awk could be short too:

awk 也可能很短:

sed ':a;/0$/{N;s/\n//;ba}'

test:

测试:

sed 'H;${x;s/\n//g;p;};/0$/!d;z;x;s/\n//g;'

回答by ekim

The rating of this answeris surprising ;s(this surprised wink emoticon pun on sed substitution is intentional) given the OP specifications: sed join lines together.

考虑到 OP 规范:sed join lines together,这个答案的评分令人惊讶;s(这个关于 sed 替换的惊讶眨眼表情双关语是故意的)。

This submission'slast comment

本次提交的最后一条评论

"if that's the case check what @ninjalj submitted"

“如果是这种情况,请检查@ninjalj 提交的内容”

also suggests checking the same answer.

还建议检查相同的答案

ie. Check using sed ':a;/0$/{N;s/\n//;ba}'verbatim

IE。使用sed ':a;/0$/{N;s/\n//;ba}'逐字检查

sed '${H;z;x;s/\n//g;p;};/0$/!{H;d;};/0$/{H;z;x;s/\n//g;}'

which will not give (do the test ;):

这不会给(做测试;):

##代码##

To get this use:

要获得此用途:

##代码##

or:

或者:

##代码##

not:

不是:

##代码##

Notes:

笔记:

##代码##

does not use branching and
is identical to:

不使用分支并且
等同于:

##代码##
  • Hcommences all sequences
  • dshort circuits further script command execution on the current line and starts the next cycle so address selectors following /0$/!can only be /0$/!!so the address selector of
    /0$/{H;z;x;s/\n//g;}is redundant and not needed.
  • if a line does not end with 0 save it in hold space
    /0$/!{H;d;}
  • if a line does end with 0 save it too and then print flush (double entendre ie. purged and lines aligned)
    /0$/{H;z;x;s/\n//g;}
  • NB ${H;z;x;s/\n//g;p;}uses /0$/ ...commands with an extra pto coerce the final print and with a now unnecessary z(to empty and reset pattern space like s/.*//)
  • H开始所有序列
  • d将当前行上的进一步脚本命令执行短路并开始下一个周期,因此接下来的地址选择器/0$/!只能是/0$/!!这样的地址选择器
    /0$/{H;z;x;s/\n//g;}是多余的并且不需要。
  • 如果一行不以 0 结尾,则将其保存在保留空间中
    /0$/!{H;d;}
  • 如果一行确实以 0 结尾,也保存它,然后打印刷新(双关语,即清除并对齐行)
    /0$/{H;z;x;s/\n//g;}
  • NB${H;z;x;s/\n//g;p;}使用/0$/ ...额外的命令p来强制最终打印和现在不必要的z(清空和重置模式空间,如 s/.*//)