我有一个像这样的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'
但数字变量让我感到茫然
答案 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