web-dev-qa-db-ja.com

シェルコマンドを使用してテキストファイルの最初の列と最後の列のみを表示する方法

Sedコマンドを使用してテキストファイルの最初の列と最後の列のみを表示する方法を理解するには、いくつかの助けが必要です。以下は、これまでのコラム1の内容です。

cat logfile | sed 's/\|/ /'|awk '{print $1}'

最後の列を表示するための私の微妙な試みは次のとおりです。

cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'

ただし、これは最初の列と最後の列を取り、それらを1つのリストにマージします。 sedおよびawkコマンドを使用して最初の列と最後の列を明確に印刷する方法はありますか?

入力例:

foo|dog|cat|mouse|lion|ox|tiger|bar
39
user70573

ほとんどあります。両方の列参照を並べて配置するだけです。

cat logfile | sed 's/|/ /' | awk '{print $1, $8}'

また、ここではcatは必要ありません。

sed 's/|/ /' logfile | awk '{print $1, $8}'

また、列区切り文字が空白ではなく|であることをawkに通知できるため、sedも必要ないことに注意してください。

awk -F '|' '{print $1, $8}' logfile

suggestions by Caleb のように、正確に8つでなくても最後のフィールドを出力するソリューションが必要な場合は、$NFを使用できます。

awk -F '|' '{print $1, $NF}' logfile

また、スペースを使用する代わりに、出力で|セパレーターを保持する場合は、出力フィールドセパレーターを指定できます。残念ながら、これは-Fフラグを使用するよりも少し不格好ですが、3つの方法があります。

  • BEGINブロックのawk自体に入力フィールドと出力フィールドの区切り記号を割り当てることができます。

    awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
    
  • これらの変数は、-vフラグを使用して、コマンドラインからawkを呼び出すときに割り当てることができます。

    awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
    
  • または単に:

    awk -F '|' '{print $1 "|" $8}' logfile
    
61
Sparhawk

とにかくawkを使用しています:

awk '{ print $1, $NF }' file
14
jasonwryan

最初から最後の||(または必要に応じてスペース)に置き換えます。

sed 's/|.*|/|/'

|が特殊なsed実装はありませんが(一部の実装では-Eまたは-rを介してextended正規表現が有効になっていない場合)、\|自体はGNU sedなどの特別なものです。したがって、|文字と一致させるつもりであれば、|をエスケープする必要があります.

スペースで置き換える場合、入力にすでに|が1つしかない行が含まれている可能性がある場合は、|.*|がそれらと一致しないように特別に処理する必要があります。それは:

sed 's/|\(.*|\)\{0,1\}/ /'

(つまり、.*|の部分をオプションにします)または:

sed 's/|.*|/ /;s/|/ /'

または:

sed 's/\([^|]*\).*|/\1 /'

入力のフィールド数に関係なく、最初と8番目のフィールドが必要な場合は、次のようになります。

cut -d'|' -f1,8


(これらはすべて、入力形式が有効なテキストであると想定して、POSIX準拠のユーティリティで動作します(特に、入力に有効な文字を形成しないバイトまたはバイトシーケンスが入力に含まれている場合、sedは通常動作しませんたとえば、UTF-8ロケールのprintf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'などの現在のロケール))。

14

自分がawkおよびsedを使用していない場合は、coreutilsを使用して同じことを実現できます。

paste <(           cut -d'|' -f1  file) \ 
      <(rev file | cut -d'|' -f1 | rev)
5
Thor

|で区切られたテキストの最初と最後のフィールドを取得しようとしているようです。

ログファイルに次のようなテキストが含まれていると思いますが、

foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo

そして、あなたは次のような出力が必要です、

foo bar
bar foo

はいの場合、ここにあなたのためのコマンドがあります

GNU sed、

sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file

例:

$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar
2
Avinash Raj

あなたはおそらくsedでそれを行うべきです-私はとにかくそうするでしょう-しかし、誰もまだこれを書いていないので、

while IFS=\| read col1 cols
do  printf %10s%-s\\n "$col1 |" " ${cols##*|}"
done <<\INPUT
foo|dog|cat|mouse|lion|ox|tiger|bar
INPUT

出力

     foo | bar
1
mikeserv