次のファイルがあります。
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
私の考えでは、最も簡単で読みやすい方法は次のとおりです。
- 最初の列の抽出(
cut
) - 抽出された列から最初の行を削除する(
tail
) - この列をソースファイル(
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
このソリューションの構造は、提供された答えとは異なります。条件付き、ループ、正規表現は必要ありません。