使用awk将单行拆分为多行编号格式

4
我正在尝试使用awk命令将该值分成三个部分。 需要帮助拆分成3个部分。
内容 = 1. 11683 (<server01>: du.size[/,free] : 0.5 % 2. 21683 (<server02>: du.size[/,free] : 1.5 % 3. 31683 (<server03>: du.size[/,free] : 3.5 % 我希望上述内容以编号系统分为三行。
所需示例输出:
1. 11683 (<server01>: du.size[/,free] : 0.5 % 
2. 21683 (<server02>: du.size[/,free] : 1.5 % 
3. 31683 (<server03>: du.size[/,free] : 3.5 %

我尝试了以下命令:
echo $content | awk -F"3. " '{ print $2 }' 

and i get

31683 (<server03>: du.size[/,free] : 3.5 %

同样的问题也发生在其他人身上,但他们仍然无法得到像上面展示的正确编号格式的样本输出。
有人可以帮我解决这个问题吗?
6个回答

6

百分号%看起来是一个很好的用于拆分的符号。尝试使用以下代码:

sed 's/% /%\n/g'

测试:

echo "1. 11683 (<server01>: du.size[/,free] : 0.5 % 2. 21683 (<server02>: du.size[/,free] : 1.5 % 3. 31683 (<server03>: du.size[/,free] : 3.5 %" | sed 's/% /%\n/g'

结果:

1. 11683 (<server01>: du.size[/,free] : 0.5 %
2. 21683 (<server02>: du.size[/,free] : 1.5 %
3. 31683 (<server03>: du.size[/,free] : 3.5 %

4
你可以使用sed代替:
sed "s#[^^]\([0-9]\.\) #\n\1 #g"

例子:

[~/Desktop]
==> echo "1. 11683 (<server01>: du.size[/,free] : 0.5 % 2. 21683 (<server02>: du.size[/,free] : 1.5 % 3. 31683 (<server03>: du.size[/,free] : 3.5 %" | sed "s#[^^]\([0-9]
\.\) #\n\1 #g"
1. 11683 (<server01>: du.size[/,free] : 0.5 %
2. 21683 (<server02>: du.size[/,free] : 1.5 %
3. 31683 (<server03>: du.size[/,free] : 3.5 %

3
perl -pe 's/(\d+\.\s)/\n$1/g'

测试过:

> echo "1. 11683 (<server01>: du.size[/,free] : 0.5 % 2. 21683 (<server02>: du.size[/,free] : 1.5 % 3. 31683 (<server03>: du.size[/,free] : 3.5 %" | perl -pe 's/(\d+\.\s)/\n$1/g'

1. 11683 (<server01>: du.size[/,free] : 0.5 % 
2. 21683 (<server02>: du.size[/,free] : 1.5 % 
3. 31683 (<server03>: du.size[/,free] : 3.5 %

1
这适用于Mac,其中sed将\n和n视为相同的东西。 - Troy Daniels

1

对于在Mac上工作的符合POSIX标准的答案:

sed -E $'s/ ([0-9]+\\. )/\\\n\\1/g'

例子:

$ echo "1. 11683 (<server01>: du.size[/,free] : 0.5 % 2. 21683 (<server02>: du.size[/,free] : 1.5 % 3. 31683 (<server03>: du.size[/,free] : 3.5 %" | sed -E $'s/ ([0-9]+\\. )/\\\n\\1/g'
1. 11683 (<server01>: du.size[/,free] : 0.5 %
2. 21683 (<server02>: du.size[/,free] : 1.5 %
3. 31683 (<server03>: du.size[/,free] : 3.5 %

工作原理

-E

开启更友好的正则表达式语法,使我们可以使用+来匹配一个或多个字符,而只需要(...)来捕获分组,而不是使用\(...\)

s/.../.../g

s/表示进行字符串替换,/g表示在一行上进行第一次替换后不要停止。

/([0-9]+\.)/

匹配' 2. '' 3. ',并捕获'2.''3.'以备后用。包括捕获组前面的空格让我们避免在'1.'前添加额外的换行符,因为'1.'在行首没有空格。捕获组内的尾随空格过滤掉类似'1.5'的内容。

/\n\1/

\n是一个换行符,\1是第一个圆括号捕获组。

$'...'和额外的反斜杠

给sed提供一个换行符的POSIX方法是输入\和一个实际的换行符:

$ echo 'a#b' | sed 's/#/\
/'
a
b

Linux是特殊的,因为GNU扩展了sed来识别\n,但在其他版本的sed(如Mac上)中,\n不被解释为换行符,我们需要使用POSIX格式。然而,为了使其成为一行代码,我们使用了$'...\\\n...',它告诉shell解释转义序列。首先,\\编码一个\,然后\n表示换行符。


1
尝试
echo "1. 11683 (<server01>: du.size[/,free] : 0.5 % 2. 21683 (<server02>: du.size[/,free] : 1.5 % 3. 31683 (<server03>: du.size[/,free] : 3.5 %" | awk '{n = split($0,array,"%"); for (i = 0; i < n-1; ++i){gsub("^ ","",array[i+1]);print array[i+1]" %",i}}'

最后两行的前导空格是不需要的,看起来最后两行是第一行的子行。 - San
谢谢指出,我没有真正测试我的代码。我已经做了更改,现在它可以正常工作了。 - Aditya Sihag

1
您的数据似乎在元素数量上是固定的。
{
    print $1, $2, $3, $4, $5, $6, $7
    print $8, $9, $10, $11, $12, $13, $14
    print $15, $16, $17, $18, $19, $20, $21
}

如果你需要对数据进行除打印之外的任何操作,这将非常有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接