我花了很长时间才找到正确的语法,使用sed
包含文件路径、正则表达式回调和算术表达式的变量。我不知道如何正确地转义。
我有一个文本文件中的文件路径,旁边有一个数字。我想找到此行并增加数字。
FILE="/home/username/scripts/test.txt"
LINE="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
sed -i -e "s,'$LINE' \([0-9]*\),'$LINE' $((\1+1))," $FILE
例如..
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
应该变成..
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
转义文件路径中的“.”的最佳方法是什么?如何正确实现\1
回调和算术表达式$((\1+1)
?
目前我收到了错误的令牌\1+1
错误。
答案1
sed
和算术不能混为一谈。适合这类工作的工具是awk
。
考虑这个测试文件:
$ cat test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 2
/another/non/matching/line 5
我们可以用以下方法增加您想要的行号:
$ line="/home/username/Pictures/properties/wallpaper/span/tree.jpg"
$ awk -v f="$line" '$0~f {$NF++} 1' test.txt
/nonmatching/line 1
/home/username/Pictures/properties/wallpaper/span/tree.jpg 3
/another/non/matching/line 5
如您所见,这会增加匹配行的数字$line
。
一个限制是,此代码不会保留数字递增的行上的多个空格。如果空格很重要,我们需要对输入格式进行更多定义。
怎么运行的
-v f="$line"
这将 shell 变量的值分配
line
给 awk 变量f
。$0~f {$NF++}
这里,是一个条件。如果输入行(表示为)与上面定义的正则表达式匹配,
$0~f
则为真。如果匹配,则执行该语句。这会增加行上的最后一个字段,对于您的输入,该字段是数字。$0
f
$NF++
1
这是 awk 中 print-the-line 的神秘简写。
使用以下方式编辑文件awk
如果您有现代 GNU awk,则可以使用以下命令编辑该文件:
gawk -i inplace -v f="$line" '$0~f {$NF++} 1' test.txt
对于其他 awk,使用:
awk -v f="$line" '$0~f {$NF++} 1' test.txt > tmp.txt && mv -f tmp.txt test.txt
text.txt
如果不存在则创建
如果文件test.txt
不包含与 匹配的行$line
,则此版本将包含以下行1
:
gawk -i inplace -v f="$line" '$0~f {n=1; $NF++} 1; END{if(!n) print f,1>>FILENAME}' test.txt
此代码添加一个变量n
。如果$line
文件中有 ,n
则将其设置为1
。如果文件中没有 ,n
则保留默认值0
。在输入文件的 处,测试END
的值。如果仍为零,则添加该行。n
n