如何使用多个循环并将输出存储到多个变量?

时间:2016-04-24 21:57:04

标签: bash

我正在尝试使用名为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

有人可以说明如何正确地做到这一点吗?

3 个答案:

答案 0 :(得分:7)

不要使用sed;只需使用参数扩展即可删除所有内容,包括URL中的最终/

while IFS= read -r url; do
    item=${url##*/}
    echo "$item $url"
done < itemlist.txt

(顺便说一下,您的问题是,sedread都在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