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

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

我有一些这样的文件:

abc 123    
abc 789  
bcd 456  
acb 135

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

期望的输出:

abc  123 abc  
abc 789 bcd  
bcd 456 acb  
acb 135 

我更喜欢使用 awk。

答案1

记住上一行:

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

这会按如下方式处理输入:

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

答案2

替代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

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

答案3

这是一种丑陋的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 ' ' - -把这些乱七八糟的东西粘在一起(将第二行附加到第三行,将第四行附加到第三行,等等)

答案4

在我看来,最简单且最易读的方法是:

  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

该解决方案背后的结构与给出的答案不同。不需要条件、循环或正则表达式。

相关内容