使用sed查找提取信息并按特定顺序打印

时间:2017-11-17 15:21:42

标签: linux bash shell

我目前正在努力找出能够提取信息然后按特定顺序打印的sed命令。例如, 如果我有一个看起来像这样的文本文件:

kashd[,]->0123asdj01234/ 
jflskdvnd1234/asdasd[,]->0123asdasd
kashd[,]->0123asdj01234/ 
jflskdvnd1234/asdasd[,]->0123asdasd
kashd[,]->0123asdj01234/ 
jflskdvnd1234/asdasd[,]->0123asdasd

然后我想提取每行的以下部分:

[,]->0132

(任意4位随机数字)和

0132/

到目前为止,我有命令:

sed 's/^.*\(\[,\]->[0-9]\{4\}\|[0-9]\{4\}\/\).*\(\[,\]->[0-9]\{4\}\|[0-9]\{4\}\/\).*$/\1      \2/; '

此命令确实提取了所有匹配项,但我的问题是我不知道如何更改订单,因为它现在打印了它找到的订单:

(如果命令在上面的示例文本上运行)

[,]->0123        1234/
1234/        [,]->0123
[,]->0123        1234/
1234/        [,]->0123
1234/        [,]->0123

但是我希望它像这样排序:

[,]->0123        1234/
[,]->0123        1234/   
[,]->0123        1234/
[,]->0123        1234/        
[,]->0123        1234/        

另外,我只允许使用sed。

2 个答案:

答案 0 :(得分:1)

GNU awk 解决方案:

awk -v FPAT='\\[,\\]->[0-9]{4}|[0-9]{4}/' '{ print ($1~/^\[/? $1 OFS $2:$2 OFS $1) }' OFS='\t' file
  • -v FPAT='\\[,\\]->[0-9]{4}|[0-9]{4}/' - 正则表达式模式定义字段值

输出:

[,]->0123   1234/
[,]->0123   1234/
[,]->0123   1234/
[,]->0123   1234/
[,]->0123   1234/
[,]->0123   1234/

答案 1 :(得分:0)

因为您不知道哪个模式会首先显示在该行中,我认为最干净的方法是使用保留空间。

以下是我在sed中的表现:

$ sed -E 'h;s/.*([[:digit:]]{4}\/).*/\1/;x;s/.*(\[,\]->[[:digit:]]{4}).*/\1/;G;s/\n/\t/' infile
[,]->0123       1234/
[,]->0123       1234/
[,]->0123       1234/
[,]->0123       1234/
[,]->0123       1234/
[,]->0123       1234/

扩大并解释:

h                                   # Copy pattern space to hold space
s/.*([[:digit:]]{4}\/).*/\1/        # Remove everything but dddd/ pattern
x                                   # Swap pattern and hold space
s/.*(\[,\]->[[:digit:]]{4}).*/\1/   # Remove everything but [,]->dddd pattern
G                                   # Append hold space to pattern space
s/\n/\t/                            # Replace line break with tab

-E选项(或旧GNU sed中的-r)允许我们不能逃避(){}。该命令在没有它的情况下也可以工作,但是我们必须改为使用\(\)\{\}

或者,如果您想使用您的命令:您可以检查一行是否不以[开头,如果是,您可以交换非空格块。如果将其添加到命令

/^\[/!s/^\([^ ]*\)\( *\)\([^ ]*\)$/\3\2\1/

它应该有用。