2016-07-08 60 views
3

我必须在txt文件中打印出一些值。 他们是按以下格式如何在打印到shell中的文本文件时保留新行?

input="Sno;Name;Field1;Field2" 

但是输出必须是:

Sno-Name 
FIELDS ALLOCATED: 
Field1 
Field2 

我这样做,像这样:

echo $input | $(awk -F';' '{print $1"-"$2}') >>$txtfile 
echo "FIELDS ALLOCATED:">>$txtfile 
echo "$input" | cut -d';' -f 3,4 >>$txtfile 

这很容易。但是,问题是Field1或Field2可能包含新行。无论何时发生这种情况,cut或awk都不会读取字段4,并将其视为新行。请帮助我如何从给定的输入格式打印两个字段(保留新行)。

+0

字段数是否固定?你对@tripleee的评论意味着没有。我问的原因是,否则似乎没有一个字段分隔符。在第一个示例中,您在字段之间显示分号,但在第二个示例中,您显示换行符。如果一个换行符是一个字段分隔符,并且你不知道有多少个字段,那么如何判断一个字段结束并且下一个字段开始? – cdarke

+0

@cdarke输入有“;”作为分隔符,我现在必须将其转换为用新行分隔的输出,同时还保留原始换行符。正如你可以看到Field1,Field2在彼此之下,所以它与多少个字段无关。例如,Field1:xxx \ n yyy Field2:zzzz \ n aaaa 它应该打印xxx \ n yyy \ n zzzz \ n aaaa – CoderBC

+0

嗯,好的,所以输入字段分隔符是一个分号。 – cdarke

回答

0
input=$'Sno;Name;Field1\nFoo;Field2' 

awk 'BEGIN{ RS = "\n\n+" ; FS = ";" } { print $1"-"$2; for(i=3;i<=NF;i++) {print $i}}' <<<"$input" 

因为它不知道有多少场可以给,我加了一个for循环,直到NF,改变了RS到一个空行,而不是换行。

2

gnu-awk可以FPAT和空RS做的工作:

input=$'Sno;Name;Field1\nFoo;Field2' 

awk -v RS= -v FPAT='[^;]+' '{ 
    printf "%s-%s\nFIELDS ALLOCATED:\n%s\n%s\n", $1, $2, $3, $4}' <<< "$input" 

Sno-Name 
FIELDS ALLOCATED: 
Field1 
Foo 
Field2 
+2

这不适用于字段值中嵌入的换行符,因为默认情况下Awk一次读取一行。 – tripleee

+0

是的没错,现在看到更新的回复。 – anubhava

+0

@anubhava如果两个换行符在一起,那么它仍然会中断。 – 123

3

如果精心形成的输入,你可以收集输入行,直到你有四个字段。

awk -F ';' 'r { $0 = r ORS $0 } 
    NR<4 { next } 
    { print $1 "-" $2 
     print "FIELDS ALLOCATED:" 
     print $3; print $4 
     print ""; r="" }' file 
+0

'$ 0 = r'意味着什么?如果输入可以有几个字段FIELD1,FIELD2,FIELD3,我们不能确定有多少? – CoderBC

+0

赋值'$ 0 = r ORS $ 0'将当前行粘贴到'r'的末尾,前面有换行符,并重新计算字段计数;所以我们在'r'中收集行,直到它包含四个字段。 – tripleee

+0

如果您不知道有多少个字段,其中一些可能包含换行符,则无法解析数据,因为格式不明确。也许有例如一种模式可以让我们识别最后一个字段的第一个字段,但是根据您提供的信息,您的问题无法在可变字段长度下解决。 – tripleee

1

只是改变awk输入记录分隔符 - RS。为了清晰起见,在每个字段周围添加了> <和>。

编辑:通过添加';'删除多余的尾部换行符在here-doc数据的末尾加上另一个条件。

input="Sno;Name;Fie 
ld1;Fi 
eld2" 

awk 'BEGIN{RS=";"} NR==1{f1=$0}; 
    NR==2{print f1 "-" $0; print "FIELDS ALLOCATED:"} 
    $0=="\n"{next} 
    NR>2{print "<" $0 ">"}' <<< "$input;" 

给出:

Sno-Name 
FIELDS ALLOCATED: 
<Fie 
ld1> 
<Fi 
eld2> 
+1

为什么field2在最后有一个额外的换行符? – 123

+0

不知道是否它的here-doc或'awk',好点(编辑)。 – cdarke

+0

这不是这里的字符串。必须是awk。 – 123

相关问题