구분된 파일의 형식을 다시 지정하고 줄을 여러 줄로 분할합니다.

구분된 파일의 형식을 다시 지정하고 줄을 여러 줄로 분할합니다.

다음과 같은 입력이 있습니다.

FIELD1   FIELD2   FIELD3   FIELD4
aaaa   bbbb   cccc   dddd
eeee   ffff
           gggg   hhhh
iiii   jjjj   kk   llll
              kk

공백으로 구분된 레코드 목록이어야 하는데 뭔가 잘못 기록되었습니다.

올바른 행은 첫 번째 행과 유사합니다. 다른 행은 중간(두 번째 행)에 줄 바꿈이 있거나 필드 내부(세 번째 행의 세 번째 필드)에 줄 바꿈이 있으므로 필드에 기록됩니다.

내가 원하는 것은 다음과 같이 주문된 출력을 얻는 것입니다.

FIELD1   FIELD2   FIELD3   FIELD4
aaaa   aaaa   aaaa   aaaa
bbbb   bbbb   bbbb   bbbb
cccc   cccc   cccc   cccc

awkROW2와 같은 행을 수정할 수 있다면 ROW3을 수정하는 것도 비슷할 것 같지만 "\n\s*"bbbb"를 "bbbb"로 바꾸는 것과 같은 일부 도구를 사용 하거나 한 번에 여러 행을 보는 방법을 이해하지 못합니다 sed. ROW2를 수정합니다.

편집하다:

제가 가지고 있는 실제 데이터의 일부는 다음과 같습니다.

G00PFMA1     transition_readonly 2   cifs     0.0.0.0/0             any
G00PFMA7     transition_export_policy_1 1
                                     nfs      10.58.91.134          sys
G00PFMA7     transition_export_policy_1 2
                                     nfs      bmczone.tsy.fm.       sys
                                              hypovereinsbank.de
G00PFMA7     transition_export_policy_1 3
                                     nfs      inf01mz2              sys

필드는 공백으로 구분됩니다. ROW1은 각 행의 모습이지만 ROW2와 ROW4에는 FIELD3과 FIELD4 사이에 줄바꿈이 있고 ROW3에는 FIELD5 내부에 줄바꿈이 있는 것으로 보입니다. 이는 Excel 파일에서 복사하여 붙여넣은 결과이므로 필드 내에 줄바꿈이 있을 수 있기 때문일 수 있습니다.

편집 2:

이 텍스트의 경우 올바른 출력은 다음과 같습니다.

G00PFMA1     transition_readonly 2   cifs     0.0.0.0/0             any
G00PFMA7     transition_export_policy_1 1 nfs      10.58.91.134          sys
G00PFMA7     transition_export_policy_1 2 nfs      bmczone.tsy.fm.hypovereinsbank.de       sys
G00PFMA7     transition_export_policy_1 3 nfs      inf01mz2              sys

답변1

먼저 분할선을 수정하고 분할 열을 무시해 보겠습니다.

$ grep -v "^\s*[^ ]*$" file | grep -o "[^ ]*" | paste - - - - - -
G00PFMA1    transition_readonly 2   cifs    0.0.0.0/0   any
G00PFMA7    transition_export_policy_1  1   nfs 10.58.91.134    sys
G00PFMA7    transition_export_policy_1  2   nfs bmczone.tsy.fm. sys
G00PFMA7    transition_export_policy_1  3   nfs inf01mz2    sys

설명하다:

  • 단일 요소만 포함하는 행을 필터링합니다.

    grep -v "^\s*[^ ]*$" file
    
  • 모든 항목을 별도의 줄에 배치

    grep -o "[^ ]*"
    
  • 행당 6개의 열로 다시 합칩니다.

    paste - - - - - -
    

귀하의 요구에 충분할 수 있지만 좋지도 않고 이식성이 떨어지는 완전한 솔루션을 얻었습니다. 분할되는 유일한 열은 열 5이고 항상 6개의 열이 있다고 가정합니다.

{
print_items(){
    # print if there are 6 elements
    if [ $# = 6 ]; then
      echo "$@"
    # print if there are 7 elements, but merge element 5 and 7 before printing
    elif [ $# = 7 ]; then
      set -- "${@:1:4}" "${5}${7}" "${@:6:1}"
      echo "$@"
    fi
}
items=()
while IFS= read -r line; do
    # Get start position of first item
    start_position=$(grep -o "^ *" <<< "$line" | wc -c)
    # if start_position is 0 then create new array items with elements in the line
    if [ $start_position = 0 ]; then
        # when new line starts, print previous line
        print_items "${items[@]}"
        items=( $line )
    # if start_position is not 0, add the elements in the line to the existing items array
    else
        items+=( $line )
    fi
    # Print items
done < file
# print last line
print_items "${items[@]}"
} | column -t

산출:

G00PFMA1  transition_readonly         2  cifs  0.0.0.0/0                          any
G00PFMA7  transition_export_policy_1  1  nfs   10.58.91.134                       sys
G00PFMA7  transition_export_policy_1  2  nfs   bmczone.tsy.fm.hypovereinsbank.de  sys
G00PFMA7  transition_export_policy_1  3  nfs   inf01mz2                           sys

관련 정보