file1.txt ファイルには次の行が含まれています。
/api/purchase/<hash>/index.html
たとえば、
/api/purchase/12ab09f46/index.html
file2.csv ファイルには次の行が含まれています。
<hash>,timestamp,ip_address
たとえば、
12ab09f46,20150812235200,22.231.113.64
a77b3ff22,20150812235959,194.66.82.11
file2.csvをフィルタリングし、file1.txtからハッシュ値も存在するすべての行を削除したいと思います。言い換えれば:
cat file1.txt | extract <hash> | sed '/<hash>/d' file2.csv
またはそのようなもの。
簡単なはずですが、うまく機能しないようです。
誰もがこのタスクに対して機能するパイプラインを提供できますか?
答え1
cut -d / -f 4 file1.txt | paste -sd '|' | xargs -I{} grep -v -E {} file2.csv
説明する:
cut -d / -f 4 file1.txt
ハッシュ値は最初のファイルから選択されます。
paste -sd '|'
すべてのハッシュ値を正規表現に連結します。H1|H2|H3
xargs -I{} grep -v -E {} file2.csv
{}
grepは前のパターンを引数として使用され、xargsは次のように置き換えられます。STDIN
ない場合は、paste
代替品に置き換えてください。tr "\\n" "|" | sed 's/|$//'
答え2
考えられるawk
解決策:
awk 'NR == FNR { x[$4] = 1; next; } { if (!($1 in x)) print $0; }' FS="/" file1.txt FS="," file2.txt
まず、(フィールド区切り文字)「/」file1.txt
を使用して読み込み、必要なハッシュ値であるフィールドFS
のキー値で配列xを作成します。次に、2番目のファイル設定を$4
読み取り、フィールド値が配列のキーとして存在しないことを確認し、存在しない場合は印刷します。コメントで提案されたより慣用的な声明は次のとおりです。file2.txt
FS
,
$1
x
awk 'NR == FNR { x[$4] = 1; next; } !($1 in x)' FS="/" file1.txt FS="," file2.txt
答え3
~のためGNU sed
sed -z 's%.*/\([^/]*\)/index.html\n%\1\\|%g;s%^%/%;s%\\|$%/d%' file1.csv |
sed -f - file2.csv
どこ最初 sedsed-command-formatでハッシュリストを生成し、/12ab09f46\|a77b3ff22\|..../d
次に送信します。Next sed-script は入力から上記のコマンドを読み取るので-f -
オプションです。
同じgrep
grep -oP '[^/]*(?=/index.html$)' file1.csv | grep -Fvf - file2.csv
またはPerl式なし:
grep -o '[^/]*/index.html$' file1.csv |
grep -o '^[^/]*' |
grep -Fvf - file2.csv
またはより良い切る:
cut -d/ -f4 file1.csv | grep -Fvf - file2.csv
答え4
次の裏地のいずれかを試してみましたが、効果があるようです。
for i in `cat file1.txt | awk -F"/" '{print $4}'`; do echo "\n $i" ; sed -ri "/^$i,/d" file2.csv ; done
まず交換してください- 内部そして- についてそれをテストするため。- についてテスト実行を実行し、すべてが正常に機能したら実行できます。- 内部