비어 있지 않은 이전 행에서 얻은 값으로 첫 번째 열의 공백을 채우는 방법은 무엇입니까?

비어 있지 않은 이전 행에서 얻은 값으로 첫 번째 열의 공백을 채우는 방법은 무엇입니까?
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

현재 행에서 공백으로 구분된 필드 수가 1개( 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는 필요한 확장 정규식을 지원하지만 이 코드는 POSIX적으로 다시 작성할 수 있습니다.

답변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

관련 정보