将上一行从文本文件复制到当前行

ban*_*nuj 7 sed awk text-processing

我有一个带行的文件,就像这样:

A
B
C
Run Code Online (Sandbox Code Playgroud)

我想在 bash 中创建一个重复文件,其中包含与下一行的副本合并的每一行,例如:

A;B
B;C
C;
Run Code Online (Sandbox Code Playgroud)

Tor*_*rin 18

使用awk

awk 'prev{ print prev ";" $0 }
     { prev = $0 }
     END { if (NR) print prev ";" }'
Run Code Online (Sandbox Code Playgroud)

根据您的输入,给出

A;B
B;C
C;
Run Code Online (Sandbox Code Playgroud)


ste*_*ver 16

Quick'n'dirty 方式(涉及读取文件两次):

$ tail -n+2 file | paste -d';' file -
A;B
B;C
C;
Run Code Online (Sandbox Code Playgroud)

  • 或者`粘贴-d';' 文件 <(sed 1d 文件)` (2认同)

Jig*_*aga 8

$ sed 'x;G;s_\n_;_;1d;${p;x;s_$_;_;}' file
A;B
B;C
C;
Run Code Online (Sandbox Code Playgroud)

sed表达式正在做什么:

  • x: 将入行保存在保持空间中,并检索上一条
  • G: 将新行(从保留空间)附加到旧行
  • s_\n_;_: 用一个替换换行符;
  • 1d: 如果这是第一行,将其删除(不要打印)并前进到下一行
  • ${...;}: 如果这是最后一行...
  • p: 首先打印连接对
  • x: 检索最后一行
  • s_$_;_: 追加最终 ;


Phi*_*pos 6

sed没有保留空间的更简单的解决方案:

sed '$!N;y/\n/;/;p;y/;/\n/;D' file
Run Code Online (Sandbox Code Playgroud)
  • $!N加入下一行(如果有的话;当不在 POSIX 模式下时$!,GNUsed不需要)
  • y/\n/;/ 将换行符替换为 ;
  • p打印结果行
  • y/;/\n/ 改回换行符,所以用
  • D 你可以去掉第一行并继续下一行


ter*_*don 5

Torin 给出awk 解决方案相同的基本思想:

$ perl -lne 'print "$last;$_" if defined $last; $last=$_;END{print "$last;" if $.}' file 
A;B
B;C
C;
Run Code Online (Sandbox Code Playgroud)

或者,如果你喜欢整个简洁的事情:

$ perl -lne'$.>1?print"$l;$_":1;$l=$_}{print"$l;"if$.' file 
A;B
B;C
C;
Run Code Online (Sandbox Code Playgroud)


Pat*_*con 5

Vim 解决方案

可以发出此命令(感谢 Conspicuous Compiler 提出这一建议):

vim "+%s/\n\(.\+\)*/;\1\n\1" sample.txt
Run Code Online (Sandbox Code Playgroud)

或者,可能更习惯的是,启动 Vim 并打开文件并发出 ex 命令:

:%s/\n\(.\+\)*/;\1\n\1
Run Code Online (Sandbox Code Playgroud)

解释:

替换模式:

  • 新行字符,\n
  • \(.+\)组成整个下一行的字符组。后面的量词*, 仅表示可以有零个或多个匹配项

具有以下内容:

  • 分号
  • 后跟对字符组的引用, \1
  • 后跟换行符, \n
  • 后跟对字符组的第二个引用,\1

前:
在此处输入图片说明

后:

在此处输入图片说明