如何用从前一个非空白行获得的值填充第一列中的空格?

如何用从前一个非空白行获得的值填充第一列中的空格?
Sample Input:
James  account
       note
       money
Ruby   account
       money
Taylor account
       note
Rob    money


Desired Output:

James  account
James  note
James  money
Ruby   account
Ruby   money
Taylor account
Taylor note
Rob    money  

正如您在上面的输出中注意到的,第一列中的所有空格都填充了从上一个非空行获得的值。我使用的是 KSH,Linux x86。我更喜欢 awk、sed。

答案1

就像是

awk 'NF>1 {x=$1; print; next} {print x,$1}' Input
James  account
James note
James money
Ruby   account
Ruby money
Taylor account
Taylor note
Rob    money

如果你想美化输出的对齐方式,请将其通过管道传递column -t

答案2

$ awk 'NF == 1 { $2 = $1; $1 = col1 } { col1 = $1; print }' file
James  account
James note
James money
Ruby   account
Ruby money
Taylor account
Taylor note
Rob    money

如果当前行上以空格分隔的字段数为一个 ( NF == 1),则将第一个字段的内容移至第二个字段(该字段为空),然后将保存的值分配col1给第一个字段。

对于所有行,将第一个字段的值保存到col1并打印。

答案3

一种方法GNU sed如下:

sed -re '                       ;# invoke GNU sed with extended regex engine
    /\S\s+\S/N                  ;# append the next line into the PS for multi-field lines
    s/^((\S+\s+).*\n)\s+/\1\2/  ;# stick the first two fields from 1st line to 2nd
    P;D                         ;# print multi-field line, & the 2nd line too now is multi-field
' input.file

输出:

James  account
James  note
James  money
Ruby   account
Ruby   money
Taylor account
Taylor note
Rob    money

限制条件:

  1. 多字段行的输入不得以空格/空格开头。
  2. GNU sed 支持所需的扩展正则表达式,尽管此代码可以改写为 POSIXly。

答案4

使用 cut 和 tr:

while IFS=$'\n' read -r line
do
    if printf -- '%s\n' "$line" | grep -E -q '^[[:blank:]]'
    then
        # is blank
        word="$(printf -- '%s\n' "$line" | tr -d '[:blank:]')"
        printf -- '%s %s\n' "$prefix" "$word"
    else
        # is not blank
        prefix="$(printf -- '%s\n' "$line" | cut -d ' ' -f 1)"
        printf -- '%s\n' "$line" | tr -s ' '
    fi
done < file

输出:

James account
James note
James money
Ruby account
Ruby money
Taylor account
Taylor note
Rob money

然后,可以用column -t如上所述

或者,没有column

length=0
while read -r line
do
    cur_length="$(printf -- '%s\n' "$line" | cut -d ' ' -f 1 | wc -c)"
    [ "$cur_length" -gt "$length" ] && length="$cur_length"
done < file

while IFS=$'\n' read -r line
do
    if printf -- '%s\n' "$line" | grep -E -q '^[[:blank:]]'
    then
        # is blank
        word="$(printf -- '%s\n' "$line" | tr -d '[:blank:]')"

        printf -- "%-${length}s%s\n" "$prefix" "$word"
    else
        # is not blank
        prefix="$(printf -- '%s\n' "$line" | cut -d ' ' -f 1 | \
          tr -d '[:blank:]')"

        suffix="$(printf -- '%s\n' "$line" | cut -d ' ' -f 2- | \
          tr -d '[:blank:]')"

        printf -- "%-${length}s%s\n" "$prefix" "$suffix"
    fi
done < file

输出:

James  account
James  note
James  money
Ruby   account
Ruby   money
Taylor account
Taylor note
Rob    money

相关内容