我有一个文件test.file,其中包含以下几行。
abc01.hostname.com
xyzabc01.hostname.com
xyzabc02.hostname.com
我有脚本-用于sed,应该打印如下输出
[abc]
abc01.hostname.com
[xyzabc]
xyzabc01.hostname.com
xyzabc02.hostname.com
但是我的输出低于输出。
[abc]
abc01.hostname.com
[abc]
[xyzabc]
xyzabc01.hostname.com
xyzabc02.hostname.com
不知道为什么[abc]被复制。有什么建议么? 下面是我正在使用的脚本。
#!/bin/bash
for i in `test.file | cut -d. -f1 | sed 's/[0-9]//g' | uniq`
do
{
name=$(cat test.file | grep ^$i[0-9] | head -1)
sed -i "/$name/i \[$i\]" test.file
}
done
答案 0 :(得分:2)
让我们清理一下。
for i in `cat test.file | cut -d. -f1 | sed 's/[0-9]//g' | uniq`
不要这样做。不要使用子外壳为for
提供列表,不要使用cat
来提供可以直接读取文件的程序,不需要子进程时不要使用长管道...
name=$(cat test.file | grep ^$i[0-9] | head -1)
如果您使用的是bash
,则不需要在每次迭代中运行三个(技术上是四个?)子过程来获得此编辑后的字符串。 c.f. this page。
#!/bin/bash
last=''
while read name
do label="${name%%[.0-9]*}"
if [[ "$label" != "$last" ]]
then echo "[$label]" # or printf "\n$label\n" for a separator line
last="$label"
fi
echo "$name"
done < test.file > file.redux
输出:
[abc]
abc01.hostname.com
[xyzabc]
xyzabc01.hostname.com
xyzabc02.hostname.com
然后,如果您对结果满意,
mv file.redux test.file
所有操作均以bash快速高效地进行,除非结果良好,否则不会产生任何东西。
如果您认为这将是很多数据,请尝试使用相同的逻辑awk
。 :)
答案 1 :(得分:2)
我不会为此使用sed
。只要做:
awk '$1 != last_prefix {print "[" $1 "]"} 1; {last_prefix=$1}' FS=[0-9] test.file
答案 2 :(得分:1)
您忘记了在sed
命令中也指示行首:
#!/bin/bash
for i in `cat test.file | cut -d. -f1 | sed 's/[0-9]//g' | uniq`
do
{
name=$(cat test.file | grep ^$i[0-9] | head -1)
sed -i "/^$name/i \[$i\]" test.file
}
done
答案 3 :(得分:0)
这可能对您有用(GNU sed):
sed -E 'G;/^([[:alpha:]]+).*\n\1/{P;d};s/\n.*//;h;s/^([[:alpha:]]+).*/[\1]\n&/' file
此解决方案通过将当前密钥与先前密钥进行比较来工作。前一个密钥存储在保留空间中,并在密钥更改时被替换。更改键后,前导字母字符将转换为由[
和]
包围的额外记录。如果键不变,则按正常方式打印当前记录。