在下一行空白区域下方的第一行中重复第一列的值

时间:2018-09-20 11:15:03

标签: linux awk sed

我从系统收到以下输入

dd/mm/yyyy

我需要将输出安排为

a b c d
  h i j
  e f g

a q w e 
  r r t
  y u i

a i o p
  j k l
  t y u

我已经尝试使用'awk'作为

a b c d
a h i j
a e f g

a q w e 
a r r t
a y u i

a i o p
a j k l
a t y u

5 个答案:

答案 0 :(得分:2)

$ awk '{if (/^ /) $1=val FS $1; else val=$1} 1' file
a b c d
a h i j
a e f g

a q w e
a r r t
a y u i

a i o p
a j k l
a t y u

答案 1 :(得分:1)

由于它被标记为linux,所以我假设gawk可用

awk -v FIELDWIDTHS='2 2 2 1' -v OFS= '{if($1=="  ")$1=p; else p=$1} 1' ip.txt
  • FIELDWIDTHS允许指定每个字段的宽度
  • 2表示两个字符,1表示一个字符,依此类推
  • -v OFS=为空的OFS,因为字段分隔符是字段值的一部分
  • if($1==" ")$1=p; else p=$1如果第一个字段为空(在此示例中为两个空格),则为其分配先前存储的值


awk -v OFS='\t' 'NF==3{$1 = p OFS $1} NF==4{p=$1; $1=$1} 1' ip.txt

这将用于改变输入字段之间的空白,并格式化输出以将制表符用作字段分隔符

答案 2 :(得分:1)

您可以按以下方式使用awk逻辑

awk 'a=/^ /{sub(/^[[:space:]]/,"",$0);$0=x$0}!a{x=$1}1' file

应按预期打印输出。

它如何工作?

  1. 对于不是以空字段开头的行,条件a=/^ /将返回0。因此,在这些行中,我们将变量$1中的x的值备份
  2. 对于以空字段开头的行,条件将为1,因此我们从现有行中剥离单个前导空格,并附加上一个值$1(变量{{1 }})

该逻辑在任何x版本中都是兼容的,并且与每一行中存在的字段数无关。

答案 3 :(得分:1)

请您尝试以下操作,因为它也可以消除初始空间。

awk '{value=$0~/^ /?value:$1} /^ /{sub(/^ +/,value OFS)} 1' Input_file

说明: 也为上述代码添加了说明。

awk '
{
  value=$0~/^ /?value:$1  ##Create variable named value whose value is variable value when line starts with space else it will be first field value.
}
/^ /{                     ##Checking if a line starts with space then do following.
  sub(/^ +/,value OFS)    ##Substituting initial space with variable value and OFS value in current line.
}
1                         ##Mentioning 1 here to print edited/non-edited value of current line.
' Input_file              ##Mentioning Input_file name here.

输出如下。

a b c d
a h i j
a e f g

a q w e
a r r t
a y u i

a i o p
a j k l
a t y u

答案 4 :(得分:0)

这可能对您有用(GNU sed):

 sed 'N;s/^\(\(\S*\s*\).*\n\)\s*\b/\1\2/;P;D' file

将非空行的开头的空白替换为第一行的前几行,然后替换其后的空格。