我试图将六行块的每个实例替换为另一个六行块,只是将两列的六行块减少为仅一列的六行块。
感谢您的评论,我会将这个问题写得更清楚。我有几个吉他谱文本文件,每个文件都有许多音乐“行”。音乐的每“行”都有 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>
以及您最喜欢的移动命令(o
并O
跳到方块的角落,以便在犯错误时可以进行调整)。
然后输入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\