如何在当前行中打印下一行的第一列?


8

我有一些像这样的文件:

abc 123    
abc 789  
bcd 456  
acb 135

我想在当前行中打印下一行的第一列。

所需的输出:

abc  123 abc  
abc 789 bcd  
bcd 456 acb  
acb 135 

我更喜欢使用awk。

Answers:


16

记住上一行:

awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'

这将按以下方式处理输入:

  • 如果当前行是第二行或更大行,则打印前一行(存储在中prev,请参见下一步)和当前行的第一字段,并用输出字段分隔符分隔(默认为空格);
  • 在所有情况下,都将当前行存储在prev变量中;
  • 在文件末尾,打印上一行。

11

替代awk方法:

$ awk 'NR == 1{printf "%s", $0;next}{printf " %s\n%s", $1,$0}' input.txt                                    
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

它的工作方式很简单:第一行是特殊情况-我们不用换行就打印它,并告诉awk转到下一行而不执行其他代码块。之后,NR == 1{printf "%s", $0;next}被跳过,但是其他部分完成了工作。

请记住,到目前为止,我们打印的格式字符串不带换行符。因此,printf " %s\n%s",$1,$0现在要做的是打印出第一个单词(并且因为没有换行,所以它保持在输出的同一行),插入换行符,然后插入整行本身(但不以换行符结尾) 。因此,下一个插入的第一个单词将保留在同一行。过程不断进行直到我们到达文件末尾。

可能的改进是包括END{print ""}插入最终换行符的块。在某些情况下,可能需要其他脚本处理生成的文件。


当用户特别要求AWK时,可以使用其他语言(例如Python)采用与打印格式化字符串相同的方法。为那些好奇如何用其他语言实现的人提供了Python替代品:

#!/usr/bin/env python
from __future__ import print_function
import sys

old = None
for index,line in enumerate(sys.stdin):
    if index == 0:
        print(line.strip(),end=" ")
        continue
    words = line.strip().split()
    print(words[0] + "\n" + line.strip(),end=" ")

用法如下:

$ ./append_first.py < input.txt                            
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

关于最终换行符的想法也适用于此。


9

这是一个sed有趣的丑陋方式

sed '2,$ s/[^ ]\+/& &/; 2,$ s/ /\n/' file | paste -d ' ' - -
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135 

说明

  • 2,$ 从第二行到最后一行
  • s/[^ ]\+/& &/ 将第一组非空白字符加倍
  • ; 分隔命令,例如在shell中
  • s/ /\n/ 用换行符替换第一个空格
  • paste -d ' ' - - 将此烂摊子粘在一起(将第二行添加到第三行,将第四行添加到第三行,等等)

1
另外,您也可以sed在没有以下情况的情况下pastesed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt
数字创伤

1
如果您编写sed有趣的程序,那么也许您应该去编码高尔夫 ;-)
Digital Trauma

1
@DigitalTrauma她已经在代码高尔夫上玩了两个月了;)
Sergiy Kolodyazhnyy

1

我认为最简单,最易读的方法是:

  1. 提取第一列(cut
  2. 从您提取的列(tail)中删除第一行
  3. 将此列粘贴到您的源文件(paste

示例:您的样本输入文件:

abc 123    
abc 789  
bcd 456  
acb 135

然后在终端中运行以下命令

cut -d' ' -f1 in.txt | tail -n +2 | paste -d' ' file -

输出:

abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135

该解决方案的结构与给定的答案不同。无需条件,循环或正则表达式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.