awkを使用して2つの位置引数の間を印刷する方法

awkを使用して2つの位置引数の間を印刷する方法

awkを使用して位置パラメータの後のすべての内容を印刷する方法はありますか?次のコマンドで印刷したいのは「p4 p5 p6 p7」です。

echo p1 p2 p3 p4 p5 p6 p7 | awk '{print $4...}'

また、2つの位置パラメータの間に印刷することも可能ですか?以下に「p4 p5 p6」を印刷します。

echo p1 p2 p3 p4 p5 p6 p7 | awk '{print $4...$6}'

正規表現を使用して次のように入力することを避けたい: awk '{print $4" "$5" "$6}'

答え1

awk(一種のループを使用せずに)これを行うことは不可能ですが、perl可能です。

ただし、perl配列は0から始まります(そして配列のawk索引付けは1から始まります)。

たとえば、次のように自動分割にperl' オプションを使用します。-aawk

$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[3..$#F]";'
p4 p5 p6 p7 

$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[2,4,6]";'
p3 p5 p7

$ echo p1 p2 p3 p4 p5 p6 p7 | perl -lane 'print "@F[1..3]";'
p2 p3 p4

注:-lPerlの行末の自動処理をオンにし、-n自動出力なしで1行ずつ入力を処理するループでラップします(sedの-nオプションに似ています。 -p同じことを行いますが、次の内容を自動的に印刷します。各入力行は確認済みです。望むよりman perlrun

配列と配列の分割の詳細については、man perldataまたはを参照してください。perldoc perlvar

配列フラグメントは二重引用符で囲まれた文字列内に印刷されるため、$"aka値を使用して$LIST_SEPARATOR配列要素を区切ります。二重引用符で囲まれた文字列の外側で印刷/使用される場合、要素間に区切り文字はまったくありません。 LIST_SEPARATORを確認man perlvarまたはperldoc perlvar検索してください。

-F最後に、フィールド区切り文字が空白(PCREで)でない場合は、Perlのoptionsを使用するか、\s+直接分割してください。例えば

$ echo "p1:p2:p3:p4:p5:p6:p7" | perl -F: -lane 'print "@F[0..4]";'
p1 p2 p3 p4 p5

$ echo "p1:p2:p3:p4:p5:p6:p7" | perl -lne '@F=split /:/; print "@F[0..4]";'
p1 p2 p3 p4 p5

答え2

パラメータが空白で確実に区切られている場合は、次のものを使用できますcut

echo p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-   # For p4 onwards
echo p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-6  # For p4 to p6

引数をスペースで区切るには、引数の構文解析方法がawkより複雑になります。私が何を言っているのか、そして上記のものがあなたが望む効果を常に得ることができない方法の例については、次のことを試してください。

printf '%s   ' p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-
printf '%s   ' p1 p2 p3 p4 p5 p6 p7 | cut -d' ' -f4-6

cut治療されている様子をご覧いただけます区切り文字としてスペースを使用するのではなく、このような区切り文字で連続するスペースを使用するわけではありませんawkawkforループを使用して必要なものを強制できます。

echo p1 p2 p3 p4 p5 p6 p7 | awk '{for (a=4;a<=NF;a++) {printf "%s ", $a} printf "\n"}'

ただし、これにより行末に末尾のスペースが残ります。この問題は解決できますが、状況はますます混乱しています。要件によっては、このcutコマンドは問題ないかもしれません。

答え3

awkの分割機能を使用して実行する方法は次のとおりです(前の回答によるとforループが必要です)。

説明する:

 "sub_0"         - variable to contain desired output ($0 substring)

 "beg"           - 1st desired field (references 4th element in "pn_ary" array)
                   (external "$beg" shell variable passed into awk (internal "beg" variable)

 "end"           - # of fields in $0 (split function loads each field in $0 as a "pn_ary[n]" element ("1-n"))

 "split(s,a,sep) - "s": string, "a": array, "sep": seperator (splits "s" per "sep", loads "a")
                   ("split" returns # of elements loaded into "pn_ary" array into "end" variable)

 "FS"            - awk system Field Seperator variable

 "[:graph:]"     - Posix bracket expression for visible ASCII chars in range "[\x21-\x7E]"   

通事論:

 beg="4"

 echo "p1 p2 p3 p4 p5 p6 p7" |\

 awk '{sub_0="";end=split($0,pn_ary,FS)
       for (i=beg;i<=end;i++) {sub_0=sub_0""FS""pn_ary[i]}     
       print substr(sub_0,match(sub_0,"[:graph:]"))
      }' beg="$beg"

出力:

p4 p5 p6 p7

関連情報