シェル コマンドを使用してテキスト ファイルの最初の列と最後の列のみを表示するにはどうすればよいですか?

シェル コマンドを使用してテキスト ファイルの最初の列と最後の列のみを表示するにはどうすればよいですか?

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

答え1

もうすぐ完了です。両方の列参照を隣り合わせに配置するだけです。

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

ここでも必要がないことに注意してくださいcat

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

awkまた、列区切り文字は空白ではなく であることがわかるので|、どちらも必要ありませんsed

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

に従って提案によるカレブ、最後のフィールドが 8 つなくても、最後のフィールドを出力するソリューションが必要な場合は、 を使用できます$NF

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

また、出力に|区切り文字を残したい場合は、スペースを使用する代わりに、出力フィールドの区切り文字を指定できます。残念ながら、フラグを使用するだけよりも少し扱いに​​くいです-Fが、次の 3 つの方法があります。

  • awkBEGIN ブロック内で、入力フィールドと出力フィールドのセパレーターを割り当てることができます。

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

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

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

答え2

とにかく使用しているawkもの:

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

答え3

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

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

sedが特別な実装はないが|延長正規表現は、一部の実装では-Eまたはでは有効になっていません-rが、\|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/|.*|/|/')。)

答え4

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

ログファイルには以下のようなテキストが含まれていると想定しました。

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

関連情報