2017-09-18 14 views
1

タブ区切りのテキストファイルの最初のセクション全体をスキップしようとしています。 (私は、カンマ区切りのサンプルデータのために変換されます。)これが動作しない理由を私はちょうど把握するように見えることはできません:データのgawkの次のコマンドが期待した結果を出力しない

CODE

gawk ' 
    /[^Country Of Sale]/ {next} 
    /^Cloud Total/ {nextfile} 
    FNR > 1 {$0 = FILENAME OFS $0; print} 
' OFS='\t' /path/to/files/*.txt > path/to/new_file.txt 

"Start Date","End Date","UPC" "4/2/17","5/6/17","SKIP THIS LINE" 
"4/2/17","5/6/17","SKIP THIS LINE" "4/2/17","5/6/17","SKIP THIS LINE" 
"4/2/17","5/6/17","SKIP THIS LINE" "4/2/17","5/6/17","SKIP THIS LINE" 
"Row Count","447","SKIP THIS LINE" 
"Country Of Sale","Total","Total Units1","Total Units2","Total C_F","SPCU","PCUT","CPS","USPS","Total Share","EffSUBS","ActSUBS" 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
"Cloud Total","1.36" "Sales Total","243.18" "Total Amount","244.54" 

EXPECTED OUTPUT

"Country Of Sale","Total","Total Units1","Total Units2","Total C_F","SPCU","PCUT","CPS","USPS","Total Share","EffSUBS","ActSUBS" 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 

また、「Country Of Sale」行をすべてのファイルのヘッダーにしたいと考えています。しかし、NR & FNRは始めに数え始めます。 「国の販売」が各ファイルの異なる行番号に表示されているので、どのようにすればいいですか?

ありがとうございました!

+2

あなたは '/ [^ Country Of Sale] /'は何をしていると思いますか?それはおそらくあなたが考えるべきことをしていないでしょう。ヒント:繰り返されるブランクの1つが余計です。 (空白は、そのネガティブ文字クラスの中で唯一の繰り返し文字です。) –

+0

それは私に何かもっと調べることができます。私はちょうど特定のプロジェクトのためにawkを学び始めています(g)。だから私は完全なnoobieだ。ありがとう。 – Steve

+0

別のヒント、 '[]'ペアを削除してください。 ....と未知の行番号にあるヘッダーをキャプチャ?私はファイルを2回処理するでしょう、最初に必要と思う '/ Country of Sale/{hdr = $ 0}'。幸いです、 – shellter

答えて

2

として

gawk ' 
    BEGIN { FS=OFS="\t" } 
    /Country Of Sale/ { f=1 } 
    /Cloud Total/ { f=0; nextfile } 
    f { print FILENAME, $0 } 
' RAW/iTunes/iTunesMatch/*.txt > munched/iTunesMatch_TEST.txt 

ルック:これを試してみてください私はコメントで、/[^Country Of Sale]/おそらくあなたが考えるべきではないとしていることに注意してください。ヒント:繰り返されるブランクの1つが余計です。

[ COSaeflnortuy](大括弧はメタキャラクタ)以外の文字を検索し、次の行にジャンプします(実際には、空白文字は空白文字ではありません)。それが見つかった場合。たとえば、行に二重引用符またはコンマが含まれている場合、その行の次の行にジャンプします(二重引用符もコンマも角括弧にはないため)。

CSVデータでは、「Cloud Total」はCの行を開始しません。二重引用符で始まります。残念ながら、正規表現を検索する正規表現では、Cが最初の文字でなければならないと主張しています。

は、私はあなたのようなものが必要だと思う:

(与えられたデータでちょうどAUラインを示しています
gawk 'FNR==1,/Country Of Sale/ { next } 
     /Cloud Total/ { nextfile } 
     { print }' data 

、あなたは、単一のコマンドライン上で同じファイルを3回を一覧表示する場合は、3行が始まる取得AUの場合は、範囲がFNR==1,/…/なので、ファイル間で問題なく動作します)。

あなたはそこからそれを取ることができるはずです。必要に応じてパターンをより限定的にすることができます(/^"Country Of Sale",/など)。 { print FILENAME OFS $0 }を使用して、ファイル名と出力フィールド区切り文字(コマンド行のタブ)の接頭辞を付けることができます。


これ、とエドの提案@あまりにも、両方は、データの行のすべてのを与えるだけではなくどのような「販売国」と「クラウド合計」の間です。

これは私が(Mac上で自作GNU Awk 4.1.3, API: 1.1を使用して、MacOSのシエラ10.12.6を実行している)得るものです:私は3回を処理するためにそれをファイルを与えたことを考えると

$ cat data 
"Start Date","End Date","UPC" "4/2/17","5/6/17","SKIP THIS LINE" 
"4/2/17","5/6/17","SKIP THIS LINE" "4/2/17","5/6/17","SKIP THIS LINE" 
"4/2/17","5/6/17","SKIP THIS LINE" "4/2/17","5/6/17","SKIP THIS LINE" 
"Row Count","447","SKIP THIS LINE" 
"Country Of Sale","Total","Total Units1","Total Units2","Total C_F","SPCU","PCUT","CPS","USPS","Total Share","EffSUBS","ActSUBS" 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
"Cloud Total","1.36" "Sales Total","243.18" "Total Amount","244.54" 
$ gawk 'FNR==1,/Country Of Sale/{next} /Cloud Total/ {nextfile} { print }' data data data 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
$ 

、それはです私はあなたが望むだろうと思っているものと思われます。その後、

gawk 'FNR==1,/Country Of Sale/ { if ($0 ~ /Country Of Sale/) print; next } 
     /Cloud Total/ { nextfile } 
     { print }' data 

そして、あなたは一度だけヘッダをしたい場合、それは多くのファイルに表示されていても、:

あなたは簡単に十分に加えることができ、出力に行を見出し、「販売国」を、必要な場合:

gawk 'FNR==1,/Country Of Sale/ { if ($0 ~ /Country Of Sale/ && hdr_count++ == 0) print; next } 
     /Cloud Total/ { nextfile } 
     { print }' data 
+0

これは私が思ったよりも厳しくなければなりません!これと@Edの提案も、「販売国」と「クラウドトータル」の間にあるのではなく、すべてのデータ行に*すべての*を与えます。私はあなたが私に教えてくれたものの様々な順列で遊んでいきます。どのような意味での教訓は貴重なものでした。 (それは私のawkのレベルです) – Steve

+0

好奇心 - 私が得たものを示す私の更新を見てください。何とかスクリプトから何かをmiscopiedしなければならないということです。 Edのスクリプトからは、データファイルのコピーごとに3行が得られます。「カントリーオブセール」行と「クラウド合計」行もスクリプトに含まれています。 –

+0

出力に 'Country Of Sale'の見出し行が必要な場合は、それを示す2番目の更新があります。 –

2

[...]は、リスト、セット、または文字の範囲を含むブラケット式です。それは、文字列または文字列の否定を含んでいません。

[^Country Of Sale] = [^aCFelnoOrStuy]

あなたはおそらく意味する場合:

!/Country Of Sale/ 

まだあなたが実際に必要なものではないとします。複数の入力ファイルがあると、一度だけ表示されるように販売ラインの国を望んでいた場合、一つのアプローチは次のようになり

$ cat file 
"Start Date","End Date","UPC" "4/2/17","5/6/17","SKIP THIS LINE" 
"4/2/17","5/6/17","SKIP THIS LINE" "4/2/17","5/6/17","SKIP THIS LINE" 
"4/2/17","5/6/17","SKIP THIS LINE" "4/2/17","5/6/17","SKIP THIS LINE" 
"Row Count","447","SKIP THIS LINE" 
"Country Of Sale","Total","Total Units1","Total Units2","Total C_F","SPCU","PCUT","CPS","USPS","Total Share","EffSUBS","ActSUBS" 
"AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
"Cloud Total","1.36" "Sales Total","243.18" "Total Amount","244.54" 

$ gawk ' 
    BEGIN { FS=OFS="\t" } 
    /Country Of Sale/ { f=1 } 
    /Cloud Total/ { f=0; nextfile } 
    f { print FILENAME, $0 } 
' file 
file "Country Of Sale","Total","Total Units1","Total Units2","Total C_F","SPCU","PCUT","CPS","USPS","Total Share","EffSUBS","ActSUBS" 
file "AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 

$ gawk ' 
    BEGIN { FS=OFS="\t" } 
    /Country Of Sale/ { f=1; if (NR==FNR) print FILENAME, $0; next} 
    /Cloud Total/ { f=0; nextfile } 
    f { print FILENAME, $0 } 
' file file file 
file "Country Of Sale","Total","Total Units1","Total Units2","Total C_F","SPCU","PCUT","CPS","USPS","Total Share","EffSUBS","ActSUBS" 
file "AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
file "AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
file "AU","0","139851331","139851331","195833.36","0.001400297","1170","1.36","","1.36","91704.63","99430" 
+0

Thanks Ed。しかし、これは、 "販売国"と "クラウドトータル"の間のものではなく、すべてのラインを私に与えるようです。 – Steve

+0

次に、コードを間違ってコピー/貼り付けます。入力したコードが、私たちに示したものと同じではありません。回答のコードでは不可能です。入力したように入力します。あなたが投稿した入力から望む出力を生成するスクリプトを表示するための質問を更新しました。 –

-1

私に必要な手がかりを与えるため@EdMorton @ @JonathanLefflerに感謝します。作業を終了したものは、/^Country Of Sale/{next} & /^Cloud Total/ {nextfile}を使用していました。次に、私は正確に把握するつもりです*なぜ*これは働いた!

+0

投稿した入力から投稿した出力を出力することはできません。 –

+0

私が投稿した入力は、フィールドの周りに二重引用符があり、区切り文字はコンマでした。元の(S.O.の簡略化されていない)データでは、区切り記号はタブであり、フィールド区切り記号はありませんでした。なぜそれが違いを生み出したのか分かりませんが、そうなったようです。 ¯\ _(ツ)_ /¯ – Steve

+0

いいえ、それはありませんでした。私が提供したコードや@JonathanLefflerのコードは、フィールドセパレータや入力の引用の有無を前提にしていませんでした。問題が何であれ、それはどちらの問題でもありません。 –

関連する問題