Unix如何基于模式连接行
我想在一个文件中连接行,如下所示 输入 输出Unix如何基于模式连接行,unix,awk,Unix,Awk,我想在一个文件中连接行,如下所示 输入 输出 01EPH087362 SHHFHDH 3673 63737 Dhdhj 01EPH636363 DHHDH 3637737Hshshhd 01EPH7373838 HDJJDJ 我希望输出如上所述;基本上每一行都应该以01EPH开始 我有awk和sed,但没有运气。如果你知道,请帮忙 awk '/^01EPH/ { if (record != "") print record; record = ""; pad = "" } { re
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737Hshshhd
01EPH7373838 HDJJDJ
我希望输出如上所述;基本上每一行都应该以01EPH开始
我有awk和sed,但没有运气。如果你知道,请帮忙
awk '/^01EPH/ { if (record != "") print record; record = ""; pad = "" }
{ record = record pad $0; pad = " " }
END { if (record != "") print record }'
如果行开始01EPH
,打印保存的信息(如果有),并清空保存的信息和填充
在每行上,将pad和新行添加到保存的信息中;将焊盘设置为空白
最后,如果保存的记录中有任何内容,请打印该记录
这甚至奇迹般地保留了DHHDH
和3637737Hshshhd
之间的双空格,因为DHHDH
结尾的行上有一个尾随空格
输出:
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737 Hshshhd
01EPH7373838 HDJJDJ
一艘班轮:
tr '\n' ' ' < file.txt | sed s/01EPH/\\n01EPH/g
tr'\n''
tr'\n'
-生成一个字符串
sed s/01EPH/\\n01EPH/g
-换行前缀01EPH输入
$ cat f
01EPH087362 SHHFHDH 3673
63737
Dhdhj
01EPH636363 DHHDH
3637737
Hshshhd
01EPH7373838 HDJJDJ
$ awk '(s=/^01EPH/) && NR>1{print ""}{printf("%s%s",(s?"":" "),$0)}END{print ""}' f
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737 Hshshhd
01EPH7373838 HDJJDJ
输出
$ cat f
01EPH087362 SHHFHDH 3673
63737
Dhdhj
01EPH636363 DHHDH
3637737
Hshshhd
01EPH7373838 HDJJDJ
$ awk '(s=/^01EPH/) && NR>1{print ""}{printf("%s%s",(s?"":" "),$0)}END{print ""}' f
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737 Hshshhd
01EPH7373838 HDJJDJ
我的看法:
awk '
/^01EPH/ {printf "%s%s", nl, $0; nl = "\n"; next}
{printf " %s", $0}
END {print ""}
' file
另一个
awk
$ $ awk 'NR>1 && /^01EPH/ {print ""}
{printf "%s", $0 OFS}
END {print ""}' file
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737 Hshshhd
01EPH7373838 HDJJDJ
当模式匹配时添加换行符(第一行除外),否则在结尾追加行…当文件只有行结尾时,可以使用
sed 's/^01EPH/\r&/;$s/$/\r/' inputfile | tr -d "\n" | tr "\r" "\n"
sed的第一部分在每个01EPH
之前插入一个\r
。第二部分在末尾附加一个,以便最后一行也以换行结束。
现在移除原始换行符,并用换行符替换标记的换行符。它会遍历文件3次,因此任何
awk
解决方案对于大文件都会更好,但我只想用sed
显示tr
这里有一个纯Bash(加上printf
)来实现这一点,它只是为了咯咯地笑:
while IFS= read -r line || [[ -n $line ]]; do
if [[ "$line" =~ ^01EPH ]]; then
printf "%s%s" "$pad" "$line"
pad=$'\n'
else
printf " %s" "$line"
fi
done <file
在这两种情况下,
awk
可能会更好……@suyog:您也可以尝试一下下面的内容,并告诉我这是否对您有帮助
awk '{printf("%s%s",($0 ~ /^01E/ && NR>1)?ORS:NR>1?FS:"",$0)} END{print ""}' Input_file
输出如下
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737 Hshshhd
01EPH7373838 HDJJDJ
在您的输出中,使用空格来分隔连接的行是不一致的。即使在中间行中的另一个字符串的中间出现,也会在每一个<代码> 01EF之前插入换行符。
tr
还删除了将其输出转换为非文本文件的所有换行符(根据POSIX),因此任何给定的sed或任何其他工具对其所做的都是未定义的行为,因此YMMV对其进行了处理。最好的情况是,它还添加了一个前导换行符和一个尾随空白字符,并且不提供一个终止换行符,以便为YMMV提供可以对该输出执行的操作。简言之,不要这样做,你是对的。无论如何,我会保留这个答案,以防万一。希望人们能读到评论:)
01EPH087362 SHHFHDH 3673 63737 Dhdhj
01EPH636363 DHHDH 3637737 Hshshhd
01EPH7373838 HDJJDJ