将包含特殊字符的变量传递给bash中的sed

时间:2014-02-28 11:21:11

标签: bash sed

我需要从文件中删除子域名:

.domain.com
.sub.domain.com -- this must be removed
.domain.com.uk
.sub2.domain.com.uk -- this must be removed

所以我使用了sed:

sed '/\.domain.com$/d' file
sed '/\.domain.com.uk$/d' file

这一部分很简单,但是当我尝试在循环中执行它时会出现问题:

while read line
do
sed '/\$line$/d' filename > filename   
done < filename

我想它是“。”和$问题,试图在很多方面逃避它,但我现在没有想法。

3 个答案:

答案 0 :(得分:2)

sed -n 's/.*/²&³/;H
$ {x;s/$/\
/
: again
  s|\(\n\)²\([^³]*\)³\(.*\)\1²[^³]*\2³|\1\2\3|
  t again
  s/[²³]//g;s/.\(.*\)./\1/
  p
  }' YourFile

将文件加载到工作缓冲区中,然后删除(迭代)以前一行结尾的任何行,最后删除结果。使用临时边缘定界符比模式

中的\ n更容易管理 GNU sed的

--posix -e(从AIX测试)

答案 1 :(得分:2)

灵感来自NeronLeVelu的想法的解决方案:

#!/bin/bash

#set -x

domains=($(rev domains | sort))

for i in `seq 0 ${#domains[@]}` ;do
    domain=${domains[$i]}
    [ -z "$domain" ] && continue
    for j in `seq $i ${#domains[@]}` ;do
        [[ ${domains[$j]} =~ $domain.+  ]] && domains[$j]=
    done
done


for i in `seq 0 ${#domains[@]}` ;do
    [ -n "${domains[$i]}" ] && echo ${domains[$i]} | rev >> result.txt
done

cat domains

.domain.com
.sub.domain.com
.domain.co.uk
.sub2.domain.co.uk
sub.domain.co.uk
abc.yahoo.com
post.yahoo.com
yahoo.com

你得到cat result.txt

.domain.co.uk
.domain.com
yahoo.com

答案 2 :(得分:0)

您的循环有点令人困惑,因为您尝试使用sed删除文件中的模式,但是您从同一文件中获取模式。

如果您确实要从filename删除子域名,那么我想您需要更多类似以下内容:

#!/bin/bash

set -x 

cp domains domains.tmp

while read domain
do
  sed -r -e "/[[:alnum:]]+${domain//./\\.}$/d" domains.tmp > domains.tmp2
  cp domains.tmp2 domains.tmp
done < dom.txt 

cat domains的位置:

.domain.com
.sub.domain.com
.domain.co.uk
.sub2.domain.co.uk
sub.domain.co.uk
abc.yahoo.com
post.yahoo.com

cat dom.txt是:

.domain.com
.domain.co.uk
.yahoo.com

在这些输入上运行脚本会导致:

$ cat domains.tmp
.domain.com
.domain.co.uk

每次迭代都会删除当前从domain读取的dom.txt子域,将其存储在临时文件中,其内容将在下一次迭代中用于其他过滤。

使用set -x尝试你的脚本是件好事,你会看到一些替换等等。