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

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 

コメント

  • サンプル入力を入力してください。

回答

ほぼそこにあります。両方の列参照を並べて配置するだけです。

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

また、ここではcatは必要ないことに注意してください。 。

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

また、awkに列区切り文字が|、空白の代わりに、sedも必要ありません。

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

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

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

また、必要に応じて|セパレーターを保持するための出力。スペースを使用する代わりに、出力フィールドセパレーターを指定できます。残念ながら、「-Fフラグを使用するよりも少し不器用ですが、ここに3つのアプローチがあります。

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

    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 

コメント

  • この問題を単純化する方法を詳しく説明します。出力セパレータとして|を使用する方法についてのメモを追加できます。文字列連結のデフォルトスペース。また、最後の列を取得するために$8をハードコーディングする代わりに$NFを使用することを説明できます。
  • その後、ファイルを更新する方法は?
  • @pankajprasad新しいファイルに書き込むh >次に古いものを上書きするか、spongeを使用します。これは本当に新しい質問です。
  • @Sparhawkは機能しますが、リーマコンテンツは消去されます。どのように対処しますか?
  • @pankajprasad新しい質問をする必要があります。 "質問"と書かれた上部の大きな青いボタンをクリックします。

回答

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

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

コメント

  • '入力フィールドの区切り文字を指定する必要はありません(この場合、 |(スペースではなく)-F\|などを使用しますか?また、彼が出力に同じ区切り文字を使用したい場合はどうなりますか?
  • @Calebおそらく:OPが入力がどのように見えるかを正確に確認するのを待っていました。動作しない例に基づいて推測します…
  • 入力に少なくとも2つのフィールドが含まれていることを前提としていることに注意してください。
  • @St é faneChazelas OPは、常に8つのフィールドがあることをコードで明確に示しています。
  • @ michaelb958 "明らかに"ケースを誇張していますが、少しだけです:)

回答

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

sed "s/|.*|/|/" 

|が特別なsedの実装はありませんが、(拡張正規表現である限り) -Eまたは一部の実装では)、\|自体はGNU sedのようなものでは特別です。したがって、|文字と一致させる場合は、|をエスケープしないでください。

スペースに置き換えて、入力に|が1つしかない行がすでに含まれている可能性がある場合は、それを特別に|.*|はそれらに一致しません。

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

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

sed "s/|.*|/ /;s/|/ /" 

または:

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

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

cut -d"|" -f1,8 

(これらはすべて、入力を前提として、POSIX準拠のユーティリティで機能します。有効なテキストを形成します(特に、sedは、たとえば

(UTF-8ロケール)))。

回答

気が狂い、sedがない場合は、 coreutilsでも同じです:

paste <( cut -d"|" -f1 file) \ <(rev file | cut -d"|" -f1 | rev) 

コメント

  • cutは、最初の列だけに関心がある場合、または区切り文字が固定されている(つまり、スペースの数が可変ではない)場合、awk / sedよりもクリーンでコンパクトです。
  • 非常にエレガントです!

回答

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

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

次のような出力

foo bar bar foo 

「はい」の場合、ここに「s」のコマンドが表示されます

GNUsedを介して

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

例:

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

コメント

  • 列はパイプで区切られていません|しかし、それらは列にあります。私はsedを使用することに興味がありますが、コマンドで行ったようにawkコマンドは使用しません。sed-r' s〜 ^([^ |] *) 。* \ |(。*)$〜\ 1 \ 2〜 'ファイル
  • "列はパイプで区切られていません|しかし、それらは列にあります"、つまり列はスペースで区切られていますか?
  • サンプルの入力と出力の方が良いでしょう。

回答

おそらく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 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です