我目前正在努力找出能够提取信息然后按特定顺序打印的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。
答案 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/
它应该有用。