AWK-列の範囲を出力します

次の形式のcsvファイルがある場合:

column1,column2,column3,column4,column5,column6,column7,column8 

そしてawkで2列目から7列目までしか印刷しないようにしたい:

awk -F"," "{print $2 "," $3 "," $4 "," $5 "," $6 "," $7}" file.csv 

そしてget:

column2,column3,column4,column5,column6,column7 

コマンドを簡略化するために列2〜7を連結する方法はありますか。かなり多くの列を持つファイルを考えているので、awkコマンドはひどく長くなります。

コメント

  • 常に連続した列のセット(2〜7、5〜15など)が必要ですか?その場合は、ループを使用して列を印刷できます。そうでない場合は、'必要な個々の列をリストすることを避けられません(ただし、必要に応じていくつかのループに混在させることができます)。また、列の数は?
  • 最後に、必要になる場合があります。優れたCSVパーサーを備えたperlやpythonのような言語を検討する…特に最初の行に列名がある場合(perl 'のCSV解析モジュールのいくつかが使用できますこれらは、列名をキーとしてハッシュを作成します。i' python 'のCSVパーサーでも同様のことができると確信しています)。perlまた、優れた配列&ハッシュスプライシング演算子もあります。
  • @casはい、列は常に連続しています。
  • これはあなたの質問に答えますか? 列の範囲をカンマ区切りで出力し、残りをカンマ区切りなしで出力

回答

$ awk -v b=2 -v e=7 "BEGIN{FS=OFS=","} {for (i=b;i<=e;i++) printf "%s%s", $i, (i<e ? OFS : ORS)}" file column2,column3,column4,column5,column6,column7 

b =開始フィールド番号、e =終了フィールド番号。引用符で囲まれたフィールド、埋め込みカンマ、改行などを含むCSVを処理する必要がある場合は、 https://stackoverflow.com/q/45420535/1745001 を参照してください。

回答

ユーティリティカットの表記はコンパクトです:

cut -d, -f2-7 <input-file> 

プロデュース:

column2、column3、column4、column5、column6、column7

@PlasmaBinturongによるコメントへの回答:私の意図は、短い呼び出しシーケンスの問題に対処することでした:" …私のawkコマンドはひどく長くなります… "。ただし、必要に応じてフィールドを配置するコードを見つけることもできます。私はawk、perl、pythonが好きですが、標準の* nixの機能を拡張するための特定のユーティリティを構築することが役立つことがよくあります。したがって、これはテストスクリプトs2からの抜粋であり、ユーティリティの再カットとアレンジを示しています。どちらも再アレンジと複製が可能で、アレンジではフィールド範囲の縮小も可能です。

FILE=${1-data1} # Utility functions: print-as-echo, print-line-with-visual-space. pe() { for _i;do printf "%s" "$_i";done; printf "\n"; } pl() { pe;pe "-----" ;pe "$*"; } pl " Input data file $FILE:" head $FILE pl " Results, cut:" cut -d, -f2-7 $FILE pl " Results, recut (modified as my-recut):" my-recut -d "," 7,6,2-5 < $FILE pl " Results, arrange:" arrange -s "," -f 5,3-1,7,5,3-4,5 $FILE 

これらのバージョンから結果を生成する:

OS, ker|rel, machine: Linux, 3.16.0-10-amd64, x86_64 Distribution : Debian 8.11 (jessie) bash GNU bash 4.3.30 cut (GNU coreutils) 8.23 recut - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) arrange (local) 1.15 ----- Input data file data1: column1,column2,column3,column4,column5,column6,column7,column8 ----- Results, cut: column2,column3,column4,column5,column6,column7 ----- Results, recut (modified as my-recut): column7,column6,column2,column3,column4,column5 ----- Results, arrange: column5,column3,column2,column1,column7,column5,column3,column4,column5 

my-recutは、textutilsコードの再カットをわずかに変更したものであり、arrangeは拡張カットのバージョンです。 。詳細:

recut Process fields like cut, allow repetitions and re-ordering. (what) Path : ~/bin/recut Version : - ( local: RepRev 1.1, ~/bin/recut, 2010-06-10 ) Length : 56 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Home : http://www1.cuni.cz/~obo/textutils/ (doc) Modules : (for perl codes) Getopt::Long 2.42 arrange Arrange fields, like cut, but in user-specified order. (what) Path : ~/bin/arrange Version : 1.15 Length : 355 lines Type : Perl script, ASCII text executable Shebang : #!/usr/bin/perl Modules : (for perl codes) warnings 1.23 strict 1.08 Carp 1.3301 Getopt::Euclid 0.4.5 

よろしくお願いします…乾杯、drl

コメント

  • Awkとは対照的に、コマンドの順序ではなく、入力ファイルの順序で列を出力します。
  • @ PlasmaBinturong-編集された回答を参照…乾杯

回答

sed -e " s/,/\n/7 ;# tag the end of col7 s/^/,/ ;# add a comma s/,/\n/2 ;# tag beginning of col2 s/.*\n\(.*\)\n.*/\1/ ;# perform surgery " file.csv 

結果:

column2,column3,column4,column5,column6,column7 

回答

以下のコマンドでテストし、正常に動作しました

awk -F "," "OFS=","{$1="";$NF="";print $0}" o| sed "s/^,//g"|sed "s/,$//g" 

出力

column2,column3,column4,column5,column6,column7 

コメント

  • 回答ありがとうございます。" o "最初のsedパイプの前:-) 2つのsedコマンドを1つに連結できます:sed "s/^,//g; s/,$//g"

行を印刷するかどうかを決定するには?他にも問題があります(たとえば、' awkを使用している場合はsedコマンドへのパイプは必要ありません!)が、そのOFSテスト部分はまったく意味がありません…

  • @EdMorton I 'まだawkソリューションのみを望んでいます…
  • @nath why ? 'が @drlが投稿したcutソリューションの何が問題になっていますか
  • @EdMortonいいえ、問題ありません。 awkでそれほど複雑になることはないと思い、技術的な理由から、興味のある問題に興味がありました:-)
  • コメントを残す

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