다음과 같은 입력이 있습니다.
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
awk
ROW2와 같은 행을 수정할 수 있다면 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