如果存在字符串(包括变量),则使用awk或sed将其翻转

时间:2015-06-16 23:05:44

标签: bash awk sed

我有一个像这样的csv文件:

,College Level Math 55,Elementary Algebra 112
,Elementary Algebra 79,
,College Level Math 102,Elementary Algebra 54
,,College Level Math 54

我需要一个执行以下操作的awk或sed命令

如果College Level Math *,Elementary Alegrbra *存在,请将其翻转,使其看起来像

Elementary Algebra *, College Level Math *

期望的输出

,Elementary Algebra 112,College Level Math 55
,Elementary Algebra 79,
,Elementary Algebra 54,College Level Math 102
,,College Level Math 54

我的问题是我不知道最后的号码,或者它是2位还是3位数。

我知道如何翻转它,如果每次都是完全相同的文字

sed -e 's/College Level Math,Elementary Algebra/Elementary Algebra,College Level Math/g'

但数字变量让我感到茫然

5 个答案:

答案 0 :(得分:2)

sed与扩展的正则表达式一起使用:

sed -r 's/(College Level Math.*?),(Elementary Algebra.*)/\2,\1/g' filepath

\1是第一个被捕获的群组(College Level Math.*?

\2是第二个被捕获的群组(Elementary Algebra.*

因此,上述sed执行从\1,\2\2,\1的替换操作

<小时/> 上述正则表达式适用于一般情况,但在以下情况下会失败:

,College Level Math 55,Elementary Algebra 111,Elementary Algebra 112
#\1=College Level Math 55,Elementary Algebra 111

,College Level Math 55,College Level Math 55,Elementary Algebra 112
#\1=College Level Math 55,College Level Math 55

所以最好不要使用像.*那样的贪婪正则表达式,相反如果条目以逗号分隔,你应该使用它:

sed -r 's/(College Level Math[^,]*),(Elementary Algebra[^,]*)/\2,\1/g' filepath

答案 1 :(得分:1)

在正则表达式中使用captures

sed 's/\(College Level Math[^,]*\),\(Elementary Algebra[^,]*\)/\2,\1/'

编辑:在我之前的一个答案中已经向我指出,为了将它们从文字转换为元字符而转义括号不符合POSIX,因此不具备可移植性。如果您可以关注可移植性,则可以省略\并使用-r选项启用扩展正则表达式语法,如Jahid的答案。

答案 2 :(得分:1)

$ awk 'BEGIN{FS=OFS=","} $2!="" && $3!=""{t=$2;$2=$3;$3=t} 1' file
,Elementary Algebra 112,College Level Math 55
,Elementary Algebra 79,
,Elementary Algebra 54,College Level Math 102
,,College Level Math 54

答案 3 :(得分:0)

另一个版本

sed 's/\(,College Level Math [0-9]\{2,3\}\)\(,Elementary Algebra [0-9]\{2,3\}\)/\2\1/' urfile

答案 4 :(得分:0)

对于给定的样本输入,这应该有效:

$ sed -r 's/(,)(College Level Math)(.*)(Elementary Algebra)(.*)/\1\4\3\2\5/g' file

上面是GNU sed

其他sed

$ sed 's/\(,\)\(College Level Math\)\(.*\)\(Elementary Algebra\)\(.*\)/\1\4\3\2\5/g' file

它捕获5个捕获组中的每一行,后来被引用为\1\4\3\2\5

请参阅后面的引用:http://www.grymoire.com/Unix/Sed.html#uh-4