Por*_*ine 4 sed awk text-processing
目标:删除每个注释块除了最后一个注释行之外的所有注释。如果文件以注释块结尾,请将其完全删除。每个注释行都以#.
我试过的命令
sed -z -e 's/#.*\n#/#/g' "${InputP}"
Run Code Online (Sandbox Code Playgroud)
输入文件
# Life/Living
# Life/Passion
- [Mindfulness.md](file:///home/nikhil/Documents/Git/Life/Passion/PassionSrc/Sports/Yoga/Mindfulness/Mindfulness.md)
# Life/PersonalManagement
# Life/Social
# Linux/AmazingNotes
# Linux/Backintime
# Linux/DotFiles
# Linux/GitScripts
- [Peaceful.m3u](file:///home/nikhil/Documents/Git/../Mobile/Documents/PortableNotes/PortableNotesSrc/SocialActivity/Music/SongsPlaylist/Data/Peaceful.m3u)
- [AuxiliaryFiles.sh](file:///home/nikhil/Documents/Git/Linux/GitScripts/GitScriptsSrc/GitInit/GitNew/Src/AuxiliaryFiles.sh)
# PythonWs/NumericalProgramming
# PythonWs/Python
# PythonWs/ScientificComputing
Run Code Online (Sandbox Code Playgroud)
预期产出
# Life/Passion
- [Mindfulness.md](file:///home/nikhil/Documents/Git/Life/Passion/PassionSrc/Sports/Yoga/Mindfulness/Mindfulness.md)
# Linux/GitScripts
- [Peaceful.m3u](file:///home/nikhil/Documents/Git/../Mobile/Documents/PortableNotes/PortableNotesSrc/SocialActivity/Music/SongsPlaylist/Data/Peaceful.m3u)
- [AuxiliaryFiles.sh](file:///home/nikhil/Documents/Git/Linux/GitScripts/GitScriptsSrc/GitInit/GitNew/Src/AuxiliaryFiles.sh)
Run Code Online (Sandbox Code Playgroud)
# PythonWs/ScientificComputing
Run Code Online (Sandbox Code Playgroud)
有谁知道如何解决问题?
问题是,.*是贪婪的,因此sed -z -e 's/#.*\n#/#/g'将匹配从包含第一行#达开始的最后一行#。这只是因为-z标志,它一次在模式空间中吞下整个文件(假设文本文件中没有空字节)。
解决您的问题的 Sed 脚本是
sed -n '/^#/N;/\n#/D;p' file
Run Code Online (Sandbox Code Playgroud)
/^#/N如果该行以 开头#,则将下一行附加到模式空间。/\n#/D如果模式空间包含一个换行符后跟#,则删除直到换行符为止的所有内容并开始新的循环。p 如果到达此命令,则打印模式空间。您显然希望从您的输入中删除所有后跟其他注释行的注释行。在sed因为正则表达式是由默认调用失败“贪婪”(即消耗尽可能地),不能轻易改变。
因此,我将为awk既定目标添加一个基于 - 的解决方案:
awk '/^#/{buf=$0;next} {if (buf) {print buf; buf=""}}1' "${InputP}"
Run Code Online (Sandbox Code Playgroud)
或者,稍微紧凑一点:
awk '/^#/{buf=$0;next} buf{print buf; buf=""}1' "${InputP}"
Run Code Online (Sandbox Code Playgroud)
1规则块的外部意味着“打印当前行,包括迄今为止所做的所有修改” - 在这种情况下没有)。/^#/),则内容将存储在缓冲区中buf,但尚未打印。该next命令将执行跳到下一行,因此剩余的代码仅适用于非注释行。