我已经制作了一个脚本来练习我的Bash,只是意识到这个脚本没有考虑制表,这是一个问题,因为它旨在查找和替换Python脚本中的模式(显然需要制表到工作)。
这是我的代码。有没有一种简单的方法来解决这个问题?
pressure=1
nline=$(cat /myfile.py | wc -l) # find the line length of the file
echo $nline
for ((c=0;c<=${nline};c++))
do
res=$( tail -n $(($(($nline+1))-$c)) myfile.py | head -n 1 | awk 'gsub("="," ",$1){print $1}' | awk '{print$1}')
#echo $res
if [ $res == 'pressure_run' ]
then
echo "pressure_run='${pressure}'" >> myfile_mod.py
else
echo $( tail -n $(($nline-$c)) myfile.py | head -n 1) >> myfile_mod.py
fi
done
基本上,它会找到包含pressure_run=something
的行,并将其替换为pressure_run=$pressure
。文件的其余部分应该不受影响。但在这种情况下,所有制表都会被删除。
答案 0 :(得分:2)
如果您想尽快进行更换,请按照shellter评论中指出的方式选择sed:
sed "s/\(pressure_run=\).*/\1$pressure/" myfile.py
对于Bash培训,正如您所说,您可能希望在您的文件上手动循环。您当前版本的一些评论:
/myfile.py
真的在根目录中吗?之后,你不会在那个地方引用它。cat ... | wc -l
是useless use of cat
,最好写成wc -l < myfile.py
。for
循环执行的时间比您的行多一次。c
行,然后告诉我这些行的第一行&# 34 ;. 必须更简单,对吗?=
替换为空格
,然后显示我结果的第一个空格分隔字段&#34;。 必须是一种更简单的方式,对吗?顺便说一下,这是你去除前导标签的地方(你的第一个awk命令就是这样做的。)可以获得所需结果的最小变化是修改awk命令:而不是
awk 'gsub("="," ",$1){print $1}' | awk '{print$1}'
你可以使用
awk -F '=' '{ print $1 }'
&#34;字段由=
分隔;给我第一个&#34;。这保留了主要标签。
替换也必须稍微调整一下;您现在想要匹配pressure_run
中结束的内容:
if [[ $res == *pressure_run ]]
我使用了更灵活的[[ ]]
代替[ ]
,并将*
添加到pressure_run
(必须不引用):&#34;如果$res
在pressure_run
结束,那么......&#34;
替换必须使用$res
,其中包含适当数量的标签:
echo "$res='${pressure}'" >> myfile_mod.py
您可以使用done > myfile_mod.py
重定向整个循环的输出,而不是每个循环追加每一行(并每次打开文件)。
这与您的版本中的字面${pressure}
一样,因为它是单引号。如果你想用$pressure
的值替换它,你必须删除单引号(这里不需要括号,但不要伤害):
echo "$res=$pressure" >> myfile_mod.py
这修复了你的例子,但应该指出的是,枚举行然后用tail | head
一次获取一行是一个非常糟糕的主意。您遍历文件的每一行两次,它非常容易出错并且难以阅读。 (感谢tripleee建议更清楚地提及这一点。)
总而言之,有一些首选的方法可以做你做的事情。你基本上循环遍历一个文件,如果一行符合pressure_run=
,你想用$pressure
(或该变量的值)替换右边的内容。我将如何做到这一点:
#!/bin/bash
pressure=1
# Regular expression to match lines we want to change
re='^[[:space:]]*pressure_run='
# Read lines from myfile.py
while IFS= read -r line; do
# If the line matches the regular expression
if [[ $line =~ $re ]]; then
# Print what we matched (with whitespace!), then the value of $pressure
line="${BASH_REMATCH[0]}"$pressure
fi
# Print the (potentially modified) line
echo "$line"
# Read from myfile.py, write to myfile_mod.py
done < myfile.py > myfile_mod.py
对于看起来像
的测试文件blah
test
pressure_run=no_tab
blah
something
pressure_run=one_tab
pressure_run=two_tabs
结果是
blah
test
pressure_run=1
blah
something
pressure_run=1
pressure_run=1
IFS=
和-r
业务,这对于保留空白非常重要)