現在行の横にある行の最初の列を印刷するには?

現在行の横にある行の最初の列を印刷するには?

次のファイルがあります。

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 }'

これは入力を次のように処理します。

  • 現在の行が2行目以上の場合は、前の行(に保存されている次のステップを参照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,$2行目から最後の行まで
  • s/[^ ]\+/& &/空白以外の文字の最初のセットを2倍にします。
  • ;シェルと同様に、別のコマンド
  • s/ /\n/最初のスペースを改行文字に置き換える
  • paste -d ' ' - -めちゃくちゃを互いに貼り付けます(2行を3行に追加し、4行を3行に追加するなど)。

答え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

このソリューションの構造は、提供された答えとは異なります。条件付き、ループ、正規表現は必要ありません。

関連情報