Windows SyncToy 日志文件包含几千行格式的内容:
xxx...C:\zzz。xxx...
和
xxx...zzz\.xxx...
其中 xxx 可以是包含任何可打印字符(包括空格和/或空白)的字符串
并且 zzz 可以是包含任何可打印字符的字符串,包括空格、反斜杠、数字、字母(任何大小写),。字符、下划线、长破折号、en 破折号
每行总是包含一个字符串 zzz。如上所示,它可能以字符 C:\ 开头,后跟一个长度不确定的字符串(但我们假设最大长度为 256 个字符),并以。字符;但它可能并不总是以 C:\ 开头,而可能只是以一些可打印字符开头。
zzz 总是从第 41 个字符(列)开始
您会发现,C:\zzz. 遵循 Windows(确切地说是 Windows 7)下文件的绝对路径名模式,尾部带有。字符,但并不总是终止反斜杠。
因此,典型的一行是:
Error: Cannot read from the source file Error: Cannot read from the source file AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-981944830-553675151-235582288-1001\. Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
另一个可能是:
Error: Cannot read from the source file C:\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020) Copying C:\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db to G:\gc\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db
我的要求是从每一行中提取每个完整路径名。因此,在上面的第一个例子中,我希望的输出是
AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-981944830-553675151-235582288-1001\.
第二部分:
C:\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db.
显然,我可以从每行中删去前 40 个字符,但这仍然会给我留下一个长度不确定的字符串,并且可能包含空格、字母数字中的任意或全部,。字符、下划线和反斜杠。
我熟悉简单的正则表达式,但我找不到构建我需要使用 grep(或 sed 或 awk 或任何最合适的工具)来提取我想要的字符串的方法。
这些文件来自 Win7,但可能会在 Linux 中进行操作。扩展的正则表达式工具可用。
如果有比使用 Linux 文本工具和正则表达式更简单的方法来处理这个问题,我也会很乐意去跟进。
答案1
[^\\]* (\S*\\\S*)
使用这个正则表达式,文本中突出显示的部分将被捕获到第一组中。
错误:无法从源文件读取 错误:无法从源文件读取应用程序数据\漫游\微软\加密\RSA\S-1-5-21-981944830-553675151-235582288-1001。访问被拒绝。(来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED))
错误:无法读取源文件C:\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db。该进程无法访问该文件,因为该文件正在被另一个进程使用。(来自 HRESULT 的异常:0x80070020)将 C:\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db 复制到 G:\gc\Users\zamenhof\AppData\Local\Microsoft\Windows\Explorer\thumbcache_256.db
解释:(或多或少从 regex101.com 复制/粘贴)
[^\\]* Match zero or more characters, excluding the backslash
\\ matches the character \ literally
* Quantifier — Matches between zero and unlimited times, as many times as possible
(space) matches the character (space) literally
1st Capturing Group (\S*\\\S*)
\S* matches any non-whitespace character
* Quantifier — Matches between zero and unlimited times, as many times as possible
\\ matches the character \ literally
\S* matches any non-whitespace character
* Quantifier — Matches between zero and unlimited times, as many times as possible
学习:要尝试使用正则表达式,您可以利用以下网站regex101.com或者regexr.com。
工具:您没有提到要使用哪些工具,但这里有一个perl
示例:
perl -lane 'print $1 if /[^\\]* (\S*\\\S*)/' file.txt