我有这样的输入:
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
我想如果我可以修复像 ROW2 这样的行,修复 ROW3 会类似,但我不明白如何使用一些工具,例如awk
或sed
一次查看多行,例如替换“\n\s*” bbbb”与“bbbb”并修复 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 "[^ ]*"
将它们重新组合在一起,每行六列
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