XARGSの各反復出力で最初の行をスキップします。

XARGSの各反復出力で最初の行をスキップします。
cut -d, -f2 parsed_repayment.csv | uniq -d | xargs -n1  -I{} grep {} parsed_repayment.csv | wc -l

デフォルトでは、各grepコマンドの最初の一致をスキップしてファイルに書きたいのですが、xargsはすべての出力をマージします。これを達成する便利な方法はありますか?

たとえば、「犬」、「猫」、「馬」という単語のリストがあるとします。 grepを使用してファイル内の3つの単語をすべて検索したいと思います。ここで、ファイルに各単語に一致する2行が含まれているとします。

dog l1
dog l2
cat l1
cat l2
horse l1
horse l2

私の予想結果は -

dog l2
cat l2
horse l2

検索した単語ごとに最初の一致をスキップしたい。さらに、各単語は異なる一致回数を有することができる。

grep以降の出力を一時ファイルに書き込み、tailコマンドを使用して最初の行を切り捨てようとしましたが、xargsは特定の単語のすべての一致を一緒に渡すため、単一の単語の最初の一致をスキップできませんでした。

答え1

のように聞こえるXYの問題そしてあなたが本当に欲しいものは:

awk -F, '$2 == prev; {prev = $2}' < parsed_repayment.csv

つまり、2番目のフィールドは前の行の2番目のフィールドと同じ行を報告します。

実際に望む答えではない質問に対する答えは次のとおりです。

cut -d, -f2 parsed_repayment.csv |
  uniq -d |
  xargs sh -c '
    for i do
      grep -e "$i" parsed_repayment.csv | tail -n +2
    done' sh

ただし、いくつかの注意事項があります。

  • xargs非常に具体的な入力形式が必要です。 2番目の列の値にスペース、一重引用符、二重引用符、またはバックスラッシュが含まれていると、正しく機能しません。
  • grep$i何をすべきか理解する正規表現-Fこの文字列は行のどこからでも検索.されます。$grep存在する2番目の領域は言うまでもありません。まったく同じ2番目のフィールド。

答え2

sed -e 1d次のように内部でパイプとして使用できます。grepxargs

xargs -n1 -I{} bash -c 'grep {} apt-installed |sed -e 1d'

だから結局:

cut -d, -f2 parsed_repayment.csv | uniq -d | xargs -n1 -I{} bash -c 'grep {} apt-installed |sed -e 1d' | wc -l

答え3

次に、最初の入力行をファイルに書き込み、残りfooをエコーし​​ます。

read line ; echo "$line" >> foo ; while read line ; do echo "$line" ; done 

テストの例は次のとおりです。

seq 0 9 | ( read line ; echo "$line" > foo ; while read line ; do echo "$line" ; done ) 
cat foo

これgrepで直接実行するのではなく、上記のスニペットxargsに出力を配置するパイプラインを実行します。grepこれにより、xargsすべての出力を接続する問題が解決されます。

内容全体が長すぎるため、フラグメントをシェルスクリプトに配置することを検討できます。ファイル名を制御したい場合。

編集する

これはスキップされたアイテムをファイルに書き、残りのアイテムを標準出力に書き込むと仮定しますが、おそらく私が間違って理解しているようです。

答え4

GNU Parallelを使用すると、次のようになります。

cut -d, -f2 parsed_repayment.csv | uniq -d |
  parallel 'grep {} parsed_repayment.csv | tail -n +2'

関連情報