フィールド区切り文字を含む最後の単語を印刷する方法

フィールド区切り文字を含む最後の単語を印刷する方法

word3,a,b,c,d,eフィールド区切り文字()を含む最後のフィールドを印刷するには,

  • 1行に3つの単語/文字列のみがあり、構造は次のとおりです。

    タイプ、パラメータ、値

ただし、値には、エスケープされていないフィールド区切り文字自体を含めることができます。ライン例:

echo word1,word2,word3,a,b,c,d,e | awk -F "," '{print $3}'

次のように印刷されます。

word3

予想される結果:

word3,a,b,c,d,e

他の例

echo 32637,921763.373,str84,str42,struj,str56,str65 | awk -F "," '{print $3}'

予想される結果:

str84,str42,struj,str56,str65 

答え1

したがって、最後のフィールドword1,word2,word3,a,b,c,d,eeで、3番目のフィールドはですword3。 3番目のフィールドから始まる行部分が欲しいようです。以下を使用する方が簡単ですcut

$ echo word1,word2,word3,a,b,c,d,e | cut -d , -f 3-
word3,a,b,c,d,e

-f 3--f x-yx〜yフィールドに適用されますが、省略されて3番目のフィールドから最後のフィールドにy移動します。

行に3つ以上のフィールドが含まれているとします。 2つのフィールドを含む入力行に空の出力行を提供し、コンマが含まれていない場合は、行を変更せずに残します(-s区切られていない行をスキップするオプションを追加できます)。

$ printf '%s\n' a a,b a,b,c a,b,c,d | cut -d , -f 3-
a

c
c,d
$ printf '%s\n' a a,b a,b,c a,b,c,d | cut -sd , -f 3-

c
c,d

これにより、awk次のことができます。

$ printf '%s\n' a a,b a,b,c a,b,c,d | awk 'sub(/^[^,]*,[^,]*,/, "")'
c
c,d

awk 'sub(/^([^,]*,){2}/, "")'このバリエーションはPOSIXですが、正規表現演算子をサポートawkしていない実装がまだあるため、移植性が低下します。){x,y}

最初の2つのフィールドを削除して削除された行のみを印刷する場合と同様に、awkprettificationとして使用されます。sedsed -n 's/^[^,]*,[^,]*,//p'

または:

$ printf '%s\n' a a,b a,b,c a,b,c,d | awk 'sub(/^[^,]*,?[^,]*,?/, "")'


c
c,d

3つ未満のフィールドを持つ行に空白行を印刷します。

答え2

方法awkは次のとおりです

awk -F "," '{for(i=3;i<NF;i++)printf("%s,", $i);print $NF}'

しかし、それは仕事のように聞こえますcut

cut -d , -f 3-

答え3

配列スライス機能を活用して使用します(のようなループは必要ありませんperl)。forawk

$ echo word1,word2,word3,a,b,c,d,e | perl -F, -lane 'print join(",",@F[2..$#F])'
word3,a,b,c,d,e

perl使用されるコマンドラインオプションの説明(man perlrun詳細については、参考資料を参照):

  • -F,自動分割フィールド区切り文字を次に設定します。,
  • -l自動行末処理を有効にします(つまり、各入力行の終わりから自動的に改行を削除し、各print-ed出力行に追加します)。
  • -a自動分割モードをオンにする - 各入力ラインは自動的に配列に分割されます@F
  • -n標準入力および/またはファイル名引数の各行を読み取り、処理します(デフォルトではスクリプト全体をwhile(<>)囲むループ)。
  • -e次の引数(引用符で囲まれた文字列)をPerlスクリプトとして実行します。

注:perl配列は1ベースではなく0ベースであるため、3番目のフィールドは3以外の配列要素2です@F[2]いいえ @F[3])。

$#Fは配列の最後の要素のインデックス番号@Fなので、「配列の3番目の要素から最後の要素までのすべての要素」を@F[2..$#F]意味します。@F


しかし、各ループの終わりに入力ラインも印刷することを除いて、-p非常に似た別のオプションがあります。前のステートメントによって入力行が変更された場合、その行は変更された状態で印刷されます。-nwhile(<>)

その用途の1つは、非常に似たスクリプトを書くことができるということです(しかし、それを除くすべてのsed機能perlとフレーズ砂糖を含む)。たとえば、同じ入力が与えられた場合、同じ出力が発生します。perlsedperl -pe 's/foo/bar/g'sed -e 's/foo/bar/g'

繰り返しますが、-nこの組み合わせを使用すると、非常に似たスクリプトを-a簡単に作成できます。awk実際、これは1行のようなものをperl -lane書く標準的な方法とほぼ同じです。awkperl

perl利点の1つsedawktrCPAN

答え4

使用sed:

sed 's/^\([^,]*,\)\{0,2\}//' <<<"$line"

関連情報