regex - sed:给定带有绝对路径的文件名,仅对文件名进行替换。仅在模式位于文件名开头时工作
问题描述
我正在研究一种 sed 替换模式,该模式将采用具有绝对路径的文件名,然后打印未更改的输入以及修改后的输入(应仅应用于文件名,而不是路径)。保证明确定义某些路径,因此它永远不会被赋予类似“test.c”的东西,在那种情况下它将是“./test.c”。
我有一些正在工作的正则表达式,但只有当要替换的部分位于文件名的开头时。我希望它可以与文件名的任何部分一起使用。
为了澄清,这里是当前行为的摘要。
INPUT PATTERN CURRENT OUTPUT DESIRED BEHAVIOR?
./test.c p;s;\(.*/\)t;\1###; ./test.c Yes
./###est.c
testdir/test.c p;s;\(.*/\)tes;\1#; testdir/test.c Yes
testdir/#t.c
./test.c p;s;\(.*/\)est;\1#; ./test.c NO
./test.c Should be ./t#.c
如您所见,这是我的模式:
p;s;\(.*/\)SubstringToFind;\1SubstringToInsert;
这是我的逻辑:
p
打印未修改的行
s
替换(是的,我们都知道)
捕获路径:任意数量的字符加上最后的“/”
SubstringToFind:在文件名的某处寻找模式。
\1
: 恢复未修改的路径
SubstringToInsert:插入修改后的文件名
我敢肯定,这只需要一点点添加,比如再添加一个“.*”,我尝试在捕获括号之后添加它,但这只是替换了指定的模式以及它之前的所有文件名字符。我确信解决方案正盯着我看,但我没有看到它。比我更熟悉正则表达式的人有什么帮助吗?谢谢!
解决方案
你确实很亲近。最后一种情况的模式est
在捕获中指定的斜杠之后立即查找,但est
不是在斜杠之后立即查找。
你需要:
$ echo ./test.c | sed -e 'p;s;\(.*/[^/]*\)est;\1#;'
./test.c
./t#.c
$
我使用了否定字符类来尽可能多地避免匹配.*
,但你也可以使用它(我不确定否定字符类实际上有什么显着的好处)。稍微严格一点的测试:
$ printf '%s\n' ./test.c ./southwest.c ./west-by-southwest.c south/west/southwestern.c |
> sed -e 'p;s;\(.*/[^/]*\)est;\1#;'
./test.c
./t#.c
./southwest.c
./southw#.c
./west-by-southwest.c
./west-by-southw#.c
south/west/southwestern.c
south/west/southw#ern.c
$
推荐阅读
- python - 比较两个 pandas 数据框列的元素并基于第三列创建一个新列
- android - 不要在 android 9 pie 上使用代理
- encryption - 非 https 会话 cookie 的 base64 解码
- ios - Xcode 10、Swift 4.2 中是否弃用了 UserDefaults?
- apache-spark - 显示在 Spark+Parquet 程序中读取的字节数
- python - pygeotools 中肯定存在的导入期间未找到的函数
- python - DLL 加载失败(无法导入 tensorflow)
- oracle - 如何在触发工资的同时获取员工的姓名?
- javascript - jquery - 检查.class是否存在&然后自动将.class添加到一页上的特定#id
- python - Python:csv.Dictreader 列上的额外逗号