使用 sed、awk、perl 或 vim 替换文本块

使用 sed、awk、perl 或 vim 替换文本块

我试图将六行块的每个实例替换为另一个六行块,只是将两列的六行块减少为仅一列的六行块。

感谢您的评论,我会将这个问题写得更清楚。我有几个吉他谱文本文件,每个文件都有许多音乐“行”。音乐的每“行”都有 6 个(与吉他弦数相同)连续的文本行。在音乐的“行”之间有空行(或带有一些文本)。通常,这六行“线”的长度约为两百列,我想通过将每六行垂直行 - 替换为六垂直行 - 来减少行的长度。

举个例子。我想将第一个块减少到第二个块。

|------------------|    |-------|            
|------------------|    |-------|    
|-0----------------|    |-0-----|   
|-2-----2-----2----|    |-2-2-2-|     
|-------2----------|    |---2---|       
|-------------0----|    |-----0-| 

我尝试过以下代码(见 unix.stackexchange1) 没有成功:

sed -i '/--/,/--/,/--/,/--/,/--/,/--/c\
-\
-\
-\
-\
-\
-' a.txt

我使用 awk、vim 或 perl 都没有得到更好的结果。

部分解决方案,例如使用 awk 和字段分隔符 empy,将是:找到两个连续的列,其字符均为空或“-”。然后删除两列之一。但我不知道该怎么做。

答案1

您发布的指法谱似乎是建立在六个字符的长片上,-x----,其中x是音品编号或破折号。就像这样:

 123456123456123456
 -x-----x-----x----
|------------------|
|------------------|
|-0----------------|
|-2-----2-----2----|
|-------2----------|
|-------------0----|

如果他们是全部有了这个间距,您只需更改片段即可删除一些破折号,而无需考虑其他线条。

$ sed -Ee 's/-(.)----/-\1/g; s/\|/-|/2' < tab
|-------| 
|-------|
|-0-----|
|-2-2-2-|
|---2---|
|-----0-|

但是,如果您在同一个文件中使用不同间距编写制表符,那么它会变得更加困难,因为我们需要识别每个制表符的间距,而且一般来说,这甚至无法从第一行完成。 (因为它可以是空的,如您的示例所示。)

对于更一般的情况,我可以提出的解决方案包括解码整个指法谱,然后重新打印它,这不适合这个答案。


请注意,sed 的/this/,/that/语法处理第一行匹配的行块/this/最后的行匹配/that/,并且块包含全部之间的线。/--/,/--/,/--/,...因此这是无稽之谈,因为有更多的模式不仅仅是块的开始和结束。

要匹配看起来像指法谱的块,您需要匹配|-,然后让块扩展六行。在 GNU sed 中,您可以使用/^|-/,+6它。

答案2

在 vim 中,使用视觉块模式突出显示要删除的列

<C-v>

以及您最喜欢的移动命令(oO跳到方块的角落,以便在犯错误时可以进行调整)。

然后输入d.

答案3

我已经通过以下方法完成了

命令

i=`awk '{print NR}' l.txt | sort -nr | sed -n '1p'`

 for ((j=1;j<=$i;j++)); do sed -n ''$j'p' filename|awk -F "" '{gsub("","\n",$0);print $0}'|sort | uniq;done| sed '/^$/d'| sed "N;s/\n/ /g"| awk '{print $NF,$1}'| sed -r "s/ //g"

输出

x\
x\
x\
x\
x\
x\

相关内容