我正在尝试使用名为itemlist.txt
的文本文件,其中包含:
http://example.com/item-a
http://example.com/item-b
http://example.com/item-c
http://example.com/item-d
http://example.com/item-e
我尝试了很多不同的代码变体。有些人只返回项目,但不返回网址。我无法弄清楚如何正确分配$url
。这是我最接近实现所需输出的方法。
#!/bin/bash
while read url; do
for item in $(sed "s/http:\/\/example.com\///g"); do
echo $item $url; done
done < itemlist.txt
所需的输出是:
item-a http://example.com/item-a
item-b http://example.com/item-b
item-c http://example.com/item-c
item-d http://example.com/item-d
item-e http://example.com/item-e
但相反,我得到了:
item-b http://example.com/item-a
item-c http://example.com/item-a
item-d http://example.com/item-a
item-e http://example.com/item-a
有人可以说明如何正确地做到这一点吗?
答案 0 :(得分:7)
不要使用sed
;只需使用参数扩展即可删除所有内容,包括URL中的最终/
。
while IFS= read -r url; do
item=${url##*/}
echo "$item $url"
done < itemlist.txt
(顺便说一下,您的问题是,sed
和read
都在itemlist.txt
读取; read
获取第一行,sed
消耗其余的。在第一次迭代后退出while
循环。)
答案 1 :(得分:3)
这个答案假设将结果打印到 stdout 就足够了;相反,如果您需要在每个输入行的 shell变量 中存储结果组件,请参阅chepner's helpful answer。
awk
可能是此处使用的最佳工具:
awk -F/ '{ print $NF, $0 }' itemlist.txt
-F/
将每个输入行按/
$NF
是每个输入行上的 last 字段$0
是完整的输入行。print
默认打印由单个空格分隔的参数(基于内置变量OFS
;设置OFS
会更改)。答案 2 :(得分:2)
好吧,awk
可能是mklement0's answer中显示的最佳工具。但是,有另一个选择没有坏处。
如果您的sed
没有-r
选项,请逃避所有问题。我使用#
作为分隔符。您可以通过转义/
作为捕获组的一部分来使用常规方法。
逻辑非常简单。你贪婪地抓住所有东西,直到捕获组中的最后一块。您捕获另一个捕获组中的最后一块,并使用它们来满足您想要的输出。
$ sed -r 's#(.*/)(.*)$#\2 \1\2#' file
item-a http://example.com/item-a
item-b http://example.com/item-b
item-c http://example.com/item-c
item-d http://example.com/item-d
item-e http://example.com/item-e