使用 sed 查找并替换多行字符串
find and replace multiple lines of string using sed
我有一个包含以下数字的输入文件
-45.0005
-43.0022
-41.002
.
.
.
我有一个目标 txt 文件
line:12 Angle=30
line:42 Angle=60
line:72 Angle=90
.
.
.
使用 sed 我想用输入文件中的第一个条目替换目标文件中 Angle 条目的第一个实例,用输入文件的第二个条目替换 Angle 的第二个条目,依此类推...
预期输出:
line:12 Angle=-45.005
line:42 Angle=-43.002
line:72 Angle=-41.002
.
.
.
这是我设法写的,但我没有得到预期的输出
a=`head -1 temp.txt`
#echo $a
sed -i "12s/Angle = .*/Angle = $a/g" $procfile
for i in {2..41..1}; do
for j in {42..1212..30}; do
c=$(( $i - 1 ))
#echo "this is the value of c: $c"
b=`head -$i temp.txt | tail -$c`
#echo "This is the value of b: $b"
sed -i "$js/Angle = .*/Angle = $b/g" $procfile 2> /dev/null
done
done
你能帮我改进脚本吗?
谢谢!
pr 在这里可能会有帮助,请试试这个:
pr -m -t target input | sed -r 's/(Angle=)[^\s]+\s+//'
请注意 - 这适用于您的前两个显示文件,您的代码假定一些不同的输入 - 例如“=”周围的空格。
您可以创建一个迭代器 i
,然后在 sed
中使用它在每一行中执行替换。
i=0;
while read -r line; do
i=$((i+1));
sed -i "${i}s/Angle=.*/Angle=${line}/g" $procfile;
done < temp.txt
所以我猜您想 paste
文件 - 逐行合并文件。然后用正则表达式替换该字段。
paste target_file input_file | sed 's/\(Angle=\)[^\t]*\t//'
这可能适合您 (GNU sed):
sed '/Angle=/R inputFile' targetFile | sed '/Angle=/{N;s/=.*\n/=/}'
在第一次 sed 调用中追加输入行。
在第二次 sed 调用中删除原来的 angle
和换行符。
所以我想出了这个解决方案
#!/bin/bash
infile=
cp $infile ORIG_${infile}
grep "Angle = " $infile | sed 's/Angle = //g' | sort -n > temp.txt
iMax=`cat temp.txt | wc -l`
jMax=`grep -n "Angle = " $infile | tail -1 | sed 's/:.*//g'`
for ((i=1,j=12; i<=${iMax} && j<=${jMax};i+=1,j+=30));do
a=`head -$i temp.txt | tail -1`
sed -i "${j}s/Angle = .*/Angle = $a/g" $infile
done
rm temp.txt
非常感谢 william pursell 阐明了 bash.
中递增 var 计数的语法
我有一个包含以下数字的输入文件
-45.0005
-43.0022
-41.002
.
.
.
我有一个目标 txt 文件
line:12 Angle=30
line:42 Angle=60
line:72 Angle=90
.
.
.
使用 sed 我想用输入文件中的第一个条目替换目标文件中 Angle 条目的第一个实例,用输入文件的第二个条目替换 Angle 的第二个条目,依此类推...
预期输出:
line:12 Angle=-45.005
line:42 Angle=-43.002
line:72 Angle=-41.002
.
.
.
这是我设法写的,但我没有得到预期的输出
a=`head -1 temp.txt`
#echo $a
sed -i "12s/Angle = .*/Angle = $a/g" $procfile
for i in {2..41..1}; do
for j in {42..1212..30}; do
c=$(( $i - 1 ))
#echo "this is the value of c: $c"
b=`head -$i temp.txt | tail -$c`
#echo "This is the value of b: $b"
sed -i "$js/Angle = .*/Angle = $b/g" $procfile 2> /dev/null
done
done
你能帮我改进脚本吗?
谢谢!
pr 在这里可能会有帮助,请试试这个:
pr -m -t target input | sed -r 's/(Angle=)[^\s]+\s+//'
请注意 - 这适用于您的前两个显示文件,您的代码假定一些不同的输入 - 例如“=”周围的空格。
您可以创建一个迭代器 i
,然后在 sed
中使用它在每一行中执行替换。
i=0;
while read -r line; do
i=$((i+1));
sed -i "${i}s/Angle=.*/Angle=${line}/g" $procfile;
done < temp.txt
所以我猜您想 paste
文件 - 逐行合并文件。然后用正则表达式替换该字段。
paste target_file input_file | sed 's/\(Angle=\)[^\t]*\t//'
这可能适合您 (GNU sed):
sed '/Angle=/R inputFile' targetFile | sed '/Angle=/{N;s/=.*\n/=/}'
在第一次 sed 调用中追加输入行。
在第二次 sed 调用中删除原来的 angle
和换行符。
所以我想出了这个解决方案
#!/bin/bash
infile=
cp $infile ORIG_${infile}
grep "Angle = " $infile | sed 's/Angle = //g' | sort -n > temp.txt
iMax=`cat temp.txt | wc -l`
jMax=`grep -n "Angle = " $infile | tail -1 | sed 's/:.*//g'`
for ((i=1,j=12; i<=${iMax} && j<=${jMax};i+=1,j+=30));do
a=`head -$i temp.txt | tail -1`
sed -i "${j}s/Angle = .*/Angle = $a/g" $infile
done
rm temp.txt
非常感谢 william pursell 阐明了 bash.
中递增 var 计数的语法