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
学んでいます。awk
sed
答え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
パールの使用:
- 最初のフィールドのすべての項目を
_
論理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の「貪欲ではない」?
数量子を使用して、.*
最初の(おそらく唯一の)下線文字とのみ一致します。
_
最初のフィールドのすべての項目を論理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
- 最初のフィールドである論理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
)を置き換えます。
- 最初のフィールド(論理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
- 最後の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ファイルシステムでも同様です。ファイル名に.
複数の文字が含まれている場合、このバージョンは期待どおりに機能しません。
- これで論理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