私はこのようないくつかのファイルを持っています:
abc 123
abc 789
bcd 456
acb 135
現在行の次の行の最初の列を印刷したい。
望ましい出力:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
私はawkを使用することを好みます。
私はこのようないくつかのファイルを持っています:
abc 123
abc 789
bcd 456
acb 135
現在行の次の行の最初の列を印刷したい。
望ましい出力:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
私はawkを使用することを好みます。
回答:
前の行を覚えてください:
awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'
これにより、入力は次のように処理されます。
prev
ます。次の手順を参照)と現在の行の最初のフィールドを出力フィールド区切り文字(デフォルトでは空白文字)で区切って印刷します。prev
変数に格納します。代替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
最終改行についても同じことが当てはまります。
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行目に追加する、など)sed
おもしろいプログラムを書いているなら、おそらくcode-golfを試してみてください;-)
私の意見では、最も単純で最も読みやすいアプローチは次のとおりです。
cut
)tail
)paste
)例:サンプルのinpultファイル:
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
このソリューションの背後にある構造は、与えられた回答とは異なります。条件、ループ、正規表現は必要ありません。
sed
ずに独自にpaste
:sed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt