【问题标题】:Looping through and modifying a list in unix遍历和修改unix中的列表
【发布时间】:2013-03-18 18:19:35
【问题描述】:
我正在尝试获取列表list1 的内容并循环遍历它们,并将它们与finger 生成的另一个列表进行比较。当在finger 中找到来自list1 的名称时,应将其从list1 中删除。
for i in $(cat list1); do
if finger | grep $i
echo "$i is online"
sed '/$i/d' <list1 >templist
mv templist list1
fi
done
list1 不会改变。脚本运行后,list1 的内容是相同的。
我认为问题与一开始的cat 有关,但我不确定。
谢谢,
瑞恩
【问题讨论】:
标签:
shell
unix
for-loop
sed
cat
【解决方案1】:
试试双引号:
sed "/$i/d" <list1 >templist
(列表中实际上没有任何$i。)
【解决方案2】:
根本不需要循环:
comm -23 <(sort list1) <(finger | sort) > tmpfile &&
mv list1 list1.bak &&
mv tmpfile list1
comm -23 file1 file2 返回 file1 中未出现在 file2 中的行。 file1 和 file2 必须排序。
【解决方案3】:
如果list1 不是很大(比如说,最多几百个),你可以这样做:
finger | egrep -v "$(paste -sd'|' list1)" > templist && mv templist list1
这是如何工作的:paste 将列表转换为管道分隔的列表,该列表使用 $(...) 构造内联到命令中,被 egrep 解释为正则表达式,并用 -v 标志取反以包含只有不匹配的行。
【解决方案4】:
保持原作的精神,我可能会按照这些思路重写它,以避免重复的手指和列表中的其他内容。
finger > fingerlist
while read aline ; do
if grep "$aline" fingerlist > /dev/null ; then
echo "$aline is online"
else
echo "$aline" > templist
fi
done < list1
[ -s templist ] && mv -f templist list1
rm fingerlist