简体   繁体   English

反向列使用sed

[英]Reverse columns in using sed

If i have a file like this: 如果我有这样的文件:

aa:bb:cc  
dd:ee:ff

I want to reverse the columns to this: 我想将列反转为:

cc bb aa  
ff ee dd

Basically reversing the columns and replacing the ":" with a " " 基本上将列反转,然后将“:”替换为“”

Ive been just trying to get the reversing down before worrying about the ":" replacement. 在担心“:”替换之前,我一直试图降低价格。 Im trying to use only sed for this. 我试图为此仅使用sed。

sed -r 's/(:.*)(.*:)/\2\1/'

Ideally this should match everything up to the first ":" then match everything after the last ":" then print them in reverse order but thats not the case. 理想情况下,这应该匹配第一个“:”之前的所有内容,然后匹配最后一个“:”之后的所有内容,然后以相反的顺序打印它们,但事实并非如此。

Any help would be nice, i feel like im close but just missing something here. 任何帮助都很好,我觉得我很亲密,但这里缺少一些东西。

If you insist using sed: 如果您坚持使用sed:

sed -r ':a;/[^:]*:[^:]*:/{s/([^:]*):([^:]*):(.*)/\2 \1:\3/;ba};/[^:]*:[^:]*$/s/([^:]*):([^:]*)$/\2 \1/;' file

little loop there. 那里的小循环。

But use awk is better: 但是使用awk更好:

awk -F: '{for(i=NF;i>1;i--)printf("%s ",$i);print $1}' file

printf won't return(plus \\n), print would. printf不会返回(加\\ n),打印会返回。

awk really is the better tool for this, but if you are restricting yourself to 3 columns, a reasonable way to use sed is: awk确实是一个更好的工具,但是如果将自己限制为3列,则使用sed的合理方法是:

$ k='\([^:]*\)'
$ sed "s/$k:$k:$k/\3 \2 \1/" input

This might work for you (GNU sed): 这可能对您有用(GNU sed):

sed -r 's/$/:\n/;ta;:a;s/^([^ :]+)\s*:(.*\n)/\2 \1/;ta;s/\n //' file

This appends a newline and another delimiter ( : ) to the end of the line. 此附加一新行和另一个分隔符( : )到行的结尾。 Then moves the first column to just after the newline and prepends a new delimiter ( 然后将第一列移到换行符之后,并添加一个新的定界符( ) to it. )。 This is repeated until the first character of the line is a newline which is then removed along with the unwanted extra new delimiter. 重复此操作,直到该行的第一个字符是换行符,然后将其与不需要的额外新定界符一起删除。

NB The ta command following the first substitution is there to reset the truth flag because the first substitution will always succeed. 注意:因为第一次替换将始终成功,所以在第一次替换之后使用ta命令可以重置真值标志。

You wrote: this should match everything up to the first ":" then match everything after the last ":" then print them in reverse order. 您写道:这应该匹配第一个“:”之前的所有内容,然后匹配最后一个“:”之后的所有内容,然后以相反的顺序打印它们。 I think you want aa:bb:cc:dd converted into dd bb cc aa . 我认为您想将aa:bb:cc:dd转换为dd bb cc aa This can be done with 这可以用

sed -e "s/^\([^:]*\):\(.*\):\([^:]*\)$/\3 \2 \1/" -e 's/:/ /g' inputfile
# Test
echo "aa:bb:cc
aa:bb:cc:dd" | sed -e "s/^\([^:]*\):\(.*\):\([^:]*\)$/\3 \2 \1/" -e 's/:/ /g'
# Output
cc bb aa
dd bb cc aa

Explanation: ^ matches start of line, $ end-of line. 说明: ^匹配行首, $结束行。 [^:]* matches a string without a : . [^:]*匹配不带:的字符串。 \\(some_match\\) remembers some_match , which can be shown with \\1 (1 is the first thing in memory). \\(some_match\\)记住some_match ,它可以用\\1 (1是内存中的第一件事)显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM