Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix如何基于模式连接行_Unix_Awk - Fatal编程技术网

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