Y 列と Z 列が NULL でない場合は、特定の数の文字を残して X 列を切り捨てます。

Y 列と Z 列が NULL でない場合は、特定の数の文字を残して X 列を切り捨てます。

awk / sedを使用してcsvをフィルタリングして、特定の列(列1など)の値を切り取り、最後の8文字を保持し、先頭をワイルドカードに置き換える方法を見つけようとしています。列がNULLと等しくありません。たとえば、列3と5

データ例:

1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,DATA,DATA,DATA,DATA

になります:

1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*.filename2.exe,NULL,DATA,DATA,DATA,DATA

私は一連のパイピングを使ってrevこのスクリプトを書いていますが、非常に非効率的で、多くのデータで作業し、スクリプトに数時間かかるので、より高度な/フィルタをcut学んでいます。awksed

答え1

awk -v c=8 'BEGIN{ FS=OFS="," }
$3!="NULL" && $5!="NULL"{ $1=(length($1)>c?"*"substr($1,length($1)-c+1):$1) }1' infile

ここではc=#、列#1の長さが8文字を超える場合にのみ「*」を追加し(保持する文字数を変更できます)、それ以外の場合は列#1を変更せずに印刷します。

答え2

パールの使用:

  1. 最初のフィールドのすべての項目を_論理AND()文字に置き換えます。つまり、両方とも「NULL」にすることはできません。&&
$ perl -F, -pe 's/^.*?_/*/ if ($F[2] ne "NULL" && $F[4] ne "NULL")' input.csv 
1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*filename2.exe,NULL,DATA,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,NULL,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,DATA,DATA,NULL,DATA

これは、Perlの「貪欲ではない」?数量子を使用して、.*最初の(おそらく唯一の)下線文字とのみ一致します。

  1. _最初のフィールドのすべての項目を論理OR()文字に置き換えます||。つまり、両方とも「NULL」であってはなりません。
$ perl -F, -pe 's/^.*?_/*/ if ($F[2] ne "NULL" || $F[4] ne "NULL")' input.csv 
1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*filename2.exe,NULL,DATA,DATA,DATA,DATA
*filename2.exe,NULL,NULL,DATA,DATA,DATA
*filename2.exe,NULL,DATA,DATA,NULL,DATA
  1. 最初のフィールドである論理ANDの最後の8文字を除くすべての文字を置き換えます。
$ perl -F, -pe 's/^.*?(.{8}),/*$1,/ if ($F[2] ne "NULL" && $F[4] ne "NULL")' input.csv 
1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*ame2.exe,NULL,DATA,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,NULL,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,DATA,DATA,NULL,DATA

これは、キャプチャグループを使用して(.{8})最初のフィールドの最後の8文字を抽出し、それを使用して文字列($1)を置き換えます。

  1. 最初のフィールド(論理OR)の最後の8文字を除くすべての文字を置き換えます。
$ perl -F, -pe 's/^.*?(.{8}),/*$1,/ if ($F[2] ne "NULL" || $F[4] ne "NULL")' input.csv 
1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*ame2.exe,NULL,DATA,DATA,DATA,DATA
*ame2.exe,NULL,NULL,DATA,DATA,DATA
*ame2.exe,NULL,DATA,DATA,NULL,DATA
  1. 最後の8文字を除くすべての文字を置き換える基本名ファイル名の一部(例:「拡張子」の前)、論理AND。
$ perl -F, -pe 's/^.*?(.{8})\./*$1./ if ($F[2] ne "NULL" && $F[4] ne "NULL")' input.csv 
1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*ilename2.exe,NULL,DATA,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,NULL,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,DATA,DATA,NULL,DATA

注:ファイル名「拡張子」は、UnixおよびLinuxファイルシステムではそれほど重要ではありません。また、古代のMS-DOS FATファイルシステムのように3文字に制限されず、複数の文字を持つことができます。最新のWindowsファイルシステムでも同様です。ファイル名に.複数の文字が含まれている場合、このバージョンは期待どおりに機能しません。

  1. これで論理ORバージョンが明らかになりました。

注:Perl配列は1ではなく0から始まります。これが3番目のフィールドがにあり、$F[2]5番目のフィールドがにある理由です$F[4]

また、ANDとORの使用の違いを示すために、サンプル入力に2行を追加しました。

$ cat input.csv 
1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,DATA,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,NULL,DATA,DATA,DATA
asvasihtiqsafsoithqwtoihwoi_filename2.exe,NULL,DATA,DATA,NULL,DATA

入力の3行目と4行目は2行目と同じです。ただし、ライン3ではフィールド3の「DATA」を「NULL」に変更し、ライン4ではフィールド5の「DATA」を変更した。 「間違っています。

答え3

#!/usr/bin/python
import re
k=open('filepath','r')
for i in k:
    kospl=i.strip().split(',')
    if (kospl[2] != "NULL"  and kospl[4] != "NULL" and kospl[0] >8):
        lk=len(kospl[0])-13
        k="*."+kospl[0][lk:]+","
        print k+",".join(kospl[1:])
    else:
        print i.strip()
~                                 

出力

1597012957a0dg9a0t593qa_filename1.exe,NULL,NULL,DATA,NULL,DATA
*.filename2.exe,NULL,DATA,DATA,DATA,DATA

関連情報