在bash中将包含特殊字符的变量传递给sed
我需要从文件中删除子域:在bash中将包含特殊字符的变量传递给sed,bash,sed,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
.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
读取行时
做
sed'/\$line$/d'文件名>文件名
完成<文件名
我想这是“.”和$的问题,我已经尝试了很多方法来摆脱它,但我现在已经没有主意了 您的循环有点混乱,因为您试图使用
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 dom.txt
是:
.domain.com
.sub.domain.com
.domain.co.uk
.sub2.domain.co.uk
sub.domain.co.uk
abc.yahoo.com
post.yahoo.com
.domain.com
.domain.co.uk
.yahoo.com
在这些输入上运行脚本会导致:
$ cat domains.tmp
.domain.com
.domain.co.uk
每次迭代将删除当前从dom.txt
读取的domain
的子域,并将其存储在临时文件中,该文件的内容将在下一次迭代中用于附加过滤
使用
set-x
尝试脚本很好,您会看到一些替换等。您的循环有点混乱,因为您试图使用sed
从文件中删除模式,但从同一文件中获取模式
sed -n 's/.*/²&³/;H
$ {x;s/$/\
/
: again
s|\(\n\)²\([^³]*\)³\(.*\)\1²[^³]*\2³|\1\2\3|
t again
s/[²³]//g;s/.\(.*\)./\1/
p
}' YourFile
如果您真的想从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 dom.txt
是:
.domain.com
.sub.domain.com
.domain.co.uk
.sub2.domain.co.uk
sub.domain.co.uk
abc.yahoo.com
post.yahoo.com
.domain.com
.domain.co.uk
.yahoo.com
在这些输入上运行脚本会导致:
$ cat domains.tmp
.domain.com
.domain.co.uk
每次迭代将删除当前从dom.txt
读取的domain
的子域,并将其存储在临时文件中,该文件的内容将在下一次迭代中用于附加过滤
使用set-x
尝试脚本很好,您将看到一些替换,等等
sed -n 's/.*/²&³/;H
$ {x;s/$/\
/
: again
s|\(\n\)²\([^³]*\)³\(.*\)\1²[^³]*\2³|\1\2\3|
t again
s/[²³]//g;s/.\(.*\)./\1/
p
}' YourFile
在工作缓冲区中加载文件,然后删除(迭代)以较早的行结尾的任何行,最后在结果之前。使用临时边缘分隔符比在模式中更易于管理\n
gnused的posix-e(从AIX测试)
在工作缓冲区中加载文件,然后删除(迭代)以较早的行结尾的任何行,最后在结果之前。使用临时边缘分隔符比在模式中更易于管理\n
--posix-e
用于GNU sed(在AIX上测试)受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域
:
.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
受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域
:
.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
这也是错误的,您只需在第一次迭代中覆盖文件,所以我应该使用VARABLE将内容加载到其中,也许?在我看来,您首先应该更好地解释您试图实现的目标:)您从哪里获得要删除的模式?从档案中?您要从哪个文件中删除?来自同一个文件?听起来很奇怪。它是一个输入参数吗?输入参数是正则表达式吗?或者输入参数只是一个域,您想自动删除它的所有子域吗?这是我在上面推的一个文本文件。我需要删除此文件中域的所有子域。实际上,我是使用sed手动编写每个域来检查的:sed'/\.domain.com$/d'文件-现在我想在循环中执行此操作在这种情况下,为什么我的答案不是解决方案呢?:)我试图理解,但我不理解。对我来说,如果只需要排除子域,似乎不需要任何循环。特别是如果你有一个关于顶级域名的简短固定列表(例如only.com和.co.uk)。如果列表较长,您可能需要一个更复杂的解决方案。这也是错误的,您只需在第一次迭代中覆盖该文件。因此,我应该使用VARABLE将内容加载到其中,也许?在我看来,您首先应该更好地解释您试图实现的目标:)您从哪里获得要删除的模式?从档案中?您要从哪个文件中删除?来自同一个文件?听起来很奇怪。它是一个输入参数吗?输入参数是正则表达式吗?或者输入参数只是一个域,您想自动删除它的所有子域吗?这是我在上面推的一个文本文件。我需要删除此文件中域的所有子域。实际上,我是使用sed手动编写每个域来检查的:sed'/\.domain.com$/d'文件-现在我想在循环中执行此操作在这种情况下,为什么我的答案不是解决方案呢?:)我试图理解,但我不理解。对我来说,如果只需要排除子域,似乎不需要任何循环。特别是如果你有一个关于顶级域名的简短固定列表(例如only.com和.co.uk)。如果列表较长,您可能需要更复杂的解决方案。您的while循环已完全中断,您的
filename``位于三个不同的位置
sed`根据默认值对文件的每一行进行操作,甚至可以在使用-i
标志时进行内联更改。问题是您正在截断传递给sed
的文件。使用-i
选项进行sed
,或者将输出重定向到临时文件并将临时文件移回/while循环完全中断,您的filename``位于三个不同的位置
sed`根据默认值对文件的每一行进行操作,甚至可以在使用-i
标志时进行内联更改。问题是您正在截断传递给sed
的文件。使用sed
的-i
选项,或将输出重定向到临时文件并将临时文件移回/检查格式;我不确定上标2和3应该代表什么字符。它们只是字符,在域名中不经常使用(直到最近),所以它们是完美的分隔符,但几乎可以使用任何字符。有了新的域名规则,其他的分隔符可能是必要的(或者至少在没有部分内容之前检查一下)啊,好吧,你故意添加它们,然后重新添加