我有一个包含以下行的文件
Dev_Campaign_1873.rpm
Dev_Campaign_1987.rpm
Dev_Campaign_9876.rpm
http://52.30.241.107:8081/artifactory/api/storage/adifact
尝试使用 sed 或任何其他命令将输出获取到以下文件中
http://52.30.241.107:8081/artifactory/api/storage/adifact/Dev_Campaign_1873.rpm
http://52.30.241.107:8081/artifactory/api/storage/adifact/Dev_Campaign_1987.rpm
http://52.30.241.107:8081/artifactory/api/storage/adifact/Dev_Campaign_9876.rpm
答案1
尝试这个 sed 脚本:它非常黑客化并且依赖于两件事:文本不包含符号“|”并且只有最后一行以“http:”开头。
:again
${
s/\n/|/g
# to include first part too
s/^/|/
:next
# modify last non processed part
s/\(.*\)|\([^|]\+\)|\(.*\)\(http:.*\)/\1|\4\/\2\n\3\4/
t next
# remove unneeded guard
s/^|//
# remove prefix
s/\(.*\n\)\([^\n]\+\)/\1/
b end
}
N
b again
:end
它是如何工作的?
假设我们有这样的输入:
aaa
bbb
http://zzz
首先,脚本将文件中的所有行合并到内部缓冲区中:
:again
${
# Here internal buffer will be processed
b end
}
N
b again
:end
这是我的脚本中很常见的情况,当 sed 无法逐行处理文本并且输入不是很大时。从第一行开始脚本不会中断,只是将下一行(“N”)读入缓冲区直到结束。
当它到达最后一行(“$”)时,它可以继续处理。当它完成时,它停止(“b end”)。人们可以不使用明确的标签来到达结尾,只需“b”也可以,但我更喜欢清晰度。
因此,现在内部缓冲区中有这样的文本:
aaa\nbbb\nhttp://zzz
接下来它用符号“|”而不是“\n”来分隔行:
s/\n/|/g
# to include first part too
s/^/|/
|aaa|bbb|http://zzz
然后它尝试找到这个模式
...|text|.....http://...
并将其更改为
...|http://...text\n.....http://...
由于所用正则表达式的贪婪性质,替换从字符串的末尾到开头进行,每一步都会消除一个符号“|”:
Initial state of buffer:
|aaa|bbb|http://zzz
After first step:
|aaa|http://zzz/bbb\nhttp://zzz
After second step:
|http://zzz/aaa\nhttp://zzz/bbb\nhttp://zzz
循环是在命令“t next”的帮助下组织的。如果最后一次替换成功,它会跳转到标签“next”。
接下来,它删除行首不需要的保护“|”:
s/^|//
http://zzz/aaa\nhttp://zzz/bbb\nhttp://zzz
最后一行:
s/\(.*\n\)\([^\n]\+\)/\1/
http://zzz/aaa\nhttp://zzz/bbb
因此,当它最终打印缓冲区时,您将得到以下信息:
http://zzz/aaa
http://zzz/bbb