使用变量用反斜杠替换文件中的行

时间:2014-12-01 00:46:10

标签: linux bash shell sed

我想将字符串%%% 添加到文本文件中某些特定行的开头
这是我的剧本:

#!/bin/bash  
a="c:\Temp"
sed "s/$a/%%%$a/g" <File.txt

这是我的File.txt内容:

d:\Temp
c:\Temp
e:\Temp

但执行时没有任何改变 我认为'sed'命令找不到模式,可能是由于变量\中的a反斜杠。 如果我使用 grep c:\Temp选项(不解释字符串),我可以找到-F行:

cat File.txt | grep -F "$a"

但是sed似乎没有实现这样的'-F`选项。

两个都不工作:

sed 's/$a/%%%$a/g' <File.txt
sed 's/"$a"/%%%"$a"/g' <File.txt

我找到了关于用sed替换的类似线程,但它们没有引用变量。

如何使用变量替换所需的行%%%字符串添加到其中?

编辑:调用脚本时可以通过参数输入$a变量,所以它将被分配为:

a=$1

3 个答案:

答案 0 :(得分:1)

试试这样:

#!/bin/sh
a='c:\\Temp'  # single quotes
sed "s/$a/%%%$a/g" <File.txt  # double quotes

输出:

Johns-MacBook-Pro:sed jcreasey$ sh x.sh
d:\Temp
e:\Temp
%%%c:\Temp

你需要双斜线&#39; \&#39;逃避&#39;。 单引号不会扩展变量。 所以你用单引号转义斜杠并将其传递给双引号。

当然你也可以这样做:

#!/bin/sh
sed 's/\(.*Temp\)/%%%&/' <File.txt

如果你想从命令行获取输入,你必须允许\也是一个转义字符。因此,用户需要键入&#39; c:\\&#39;或者口译员只会等待另一个角色。一旦你得到它,你将需要再次逃脱它。 (printf%q)。

#!/bin/sh
b=`printf "%q" $1`
sed "s/\($b\)/%%% &/" < File.txt

答案 1 :(得分:1)

使用$ 1

的位置参数创建脚本
#!/bin/bash  
a="$1"
cat <file path>|sed "s/"$1"/%%%"$1"/g" > "temporary file"

现在每当你想要sed找到&#34; c:\ Temp&#34;您需要使用脚本命令行,如下所示

  bash <my executing script> c:\\\\Temp

第一个反斜杠将使bash解释后面的任何反斜杠,因此将保存在变量&#34; a&#34;在你的执行脚本中是&#34; c:\\ Temp&#34;。现在用sed中的这个变量替换将导致sed解释1个反冲,因为这个变量中的第一个反斜杠将导致sed开始解释其他反冲。

当您打开临时文件时,您将看到:

d:\Temp
%%%c:\Temp
e:\Temp

答案 2 :(得分:1)

您遇到的问题与替换您的变量有关,提供正则表达式查找文字c:Temp,其中\被shell解释为转义 。有许多解决方法。看到评论并完成了各种可能性,以下内容将允许不带引号的搜索词输入:

#!/bin/bash

## validate that needed input is given on the command line
[ -n "$1" -a "$2" ] || {
    printf "Error: insufficient input. Usage:  %s <term> <file>\n" "${0//*\//}" >&2
    exit 1
}

## validate that the filename given is readable
[ -r "$2" ] || {
    printf "Error: file not readable '%s'\n" "$2" >&2
    exit 1
}

a="$1"        # assign a
filenm="$2"   # assign filename

## test and fix the search term entered
[[ "$a" =~ '/' ]] || a="${a/:/:\\}"  # test if \ removed by shell, if so replace
a="${a/\\/\\\\}"                     # add second \

sed -e "s/$a/%%%$a/g" "$filenm"      # call sed with output to stdout

<强>用法:

$ bash sedwinpath.sh c:\Temp dat/winpath.txt
d:\Temp
%%%c:\Temp
e:\Temp

注意:这允许dos路径搜索词的single-quotedunquoted条目。要就地编辑,请使用sed -i。此外,[[运算符和=~运算符仅限于bash。


我可以发誓原来的问题说替换,但要追加,就像你在评论中提出的那样。我用以下代码更新了代码:

sed -e "s/$a/%%%$a/g" "$filenm"

提供新输出:

$ bash sedwinpath.sh c:\Temp dat/winpath.txt
d:\Temp
%%%c:\Temp
e:\Temp

请记住:如果您要编辑文件 ,请使用sed -ised -i.bak编辑实际文件(如果{ {1}}在-i.bak)中创建原始文件的备份。如果这不符合你的意图,请告诉我,我很乐意再次编辑。