我有一个名为file.txt
的文件,其中包含绝对路径。它看起来像这样:
J:/Folder/inner
J:/Folder/inner2
首先,我想编写一个用J:/
替换/cygdrive/j/
的bash脚本。所以我这样做了:
sed -i 's/J:\//\/cygdrive\/j\//g' file.txt
它按预期工作。
但现在我想要更复杂的东西:绝对路径不必从qazxswpo开始 - 它们可以从J
,C
,D
开始...
我想做与上面相同的事情,只是因为我不知道第一个字母是什么。例如:E
将成为C:/Folder/inner
,/cygdrive/c/Folder/inner
将成为D:/Folder/inner
。
我知道我需要使用正则表达式来实现这一点,但我还没有找到这样做的方法。你知道我怎么能得到我想要的东西?
要使用/cygdrive/d/Folder/inner
,你需要支持改变sed
提供的案例。因此,这不是一个便携式解决方案
GNU sed
$ cat file.txt
J:/Folder/inner
J:/Folder/inner2
C:/Folder/inner
D:/Folder/inner
$ sed -E 's#^(.):#/cygdrive/\l\1#' file.txt
/cygdrive/j/Folder/inner
/cygdrive/j/Folder/inner2
/cygdrive/c/Folder/inner
/cygdrive/d/Folder/inner
启用ERE,在这种情况下避免必须逃离-E
有些版本可能只支持()
而不是-r
-E
从一开始就匹配一个角色和^(.):
根据需要使用:
或^([A-Z]):
来匹配字母表^([A-Za-z]):
在替换部分,将使用字符串/cygdrive/\l\1
和小写版本的捕获字符/cygdrive/
作为分隔符,有助于避免在搜索/替换部分中转义#
s
可以使用除/
和换行符之外的任何字符\
我会使用-i
来解决这个问题,使用Awk
进行小写转换,并使用字段分隔符设置为tolower()
打印其余字段
:
这基本上意味着在下限(awk -F: '{print "/cygdrive/"tolower($1)""$2}' file.txt
)之后打印$1
值并在其后附加J
(其余的字符串)。 $2
只表示没有任何字符存在的空字符串。你也可以删除它们。
一旦发现名称被正确替换,请更改源文件本身
""
在如下的示例文件上
awk -F: '{print "/cygdrive/"tolower($1)""$2}' file.txt > temp && mv temp file.txt
该命令生成一个输出文件
J:/Folder/inner
J:/Folder/inner2
C:/Folder/inner
D:/Folder/inner
/cygdrive/j/Folder/inner
/cygdrive/j/Folder/inner2
/cygdrive/c/Folder/inner
/cygdrive/d/Folder/inner
的另一个变种,如果你安装了它,
perl