Sed并没有取代所有出现的模式

时间:2013-09-30 02:25:42

标签: bash sed

我有一个格式为LINES的以下变量date;album;song;duration;singer;author;genre

August 2013;MDNA;Falling Free;00:31:40;Madonna;Madonna;Pop
August 2013;MDNA;I don't give a;00:45:40;Madonna;Madonna;Pop
August 2013;MDNA;I'm a sinner;01:00:29;Madonna;Madonna;Pop
August 2013;MDNA;Give Me All Your Luvin';01:15:02;Madonna;Madonna;Pop

我想输出author-song,所以我制作了这个脚本:

echo $LINES | sed s_"^[^;]*;[^;]*;\([^;]*\);[^;]*;[^;]*;\([^;]*\)"_"\2-\1"_g

所需的输出是:

Madonna-Falling Free
Madonna-I don't give a
Madonna-I'm a sinner
Madonna-Give Me All Your Luvin'

然而,我得到了这个:

Madonna-Falling Free;Madonna;Pop August 2013;MDNA;I don't give a;00:45:40;Madonna;Madonna;Pop August 2013;MDNA;I'm a sinner;01:00:29;Madonna;Madonna;Pop August 2013;MDNA;Give Me All Your Luvin';01:15:02;Madonna;Madonna;Pop

为什么?

编辑:我需要使用sed。

4 个答案:

答案 0 :(得分:3)

当我在输入上运行sed脚本时,我得到了这个输出:

Madonna-Falling Free;Pop
Madonna-I don't give a;Pop
Madonna-I'm a sinner;Pop
Madonna-Give Me All Your Luvin';Pop

除了额外的;Pop之外没问题 - 您只需要在正则表达式的末尾添加.*$,以便替换整行。

根据您报告的输出,我猜您的输入文件正在使用与sed所期望的不同的换行约定。

无论如何,使用sed这是一件非常愚蠢的事情。比awk更好,例如:

awk 'BEGIN {FS=";";OFS="-"} {print $5,$3}'

或稍微简洁一点,

awk -F\; -vOFS=- '{print $5,$3}'

答案 1 :(得分:1)

如果您希望sed看到多行输入,则必须引用变量以回显:

echo "$LINES" | sed ...

请注意,我甚至不会尝试评估sed脚本的正确性;使用sed这里是一个讽刺,因为awk更适合这项任务。

答案 2 :(得分:0)

看起来sed正在将整个示例文本视为一行。所以它正在执行所要求的操作,然后保持其余部分不变 我会首先研究换行问题。你如何填充$ LINES?
您还应该在输入(流派)中添加第七个字段的模式,以便表达式实际上消耗了您希望它的所有文本。并且可能将模式的结尾锚定在$\b(字边界)或\s(空格字符)或\n(换行符)上。

答案 3 :(得分:0)

如果您的格式绝对是永久性的,请尝试以下内容:

echo $line | sed 's#.*;.*;\(.*\);.*;.*;\(.*\);.*#\2-\1#'