3番目またはn番目の文字が発生した後、CSVの特定の列にあるデータを切り捨てようとするフィルタが原因で問題が発生しています\
。
私のデータは次のとおりです。
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
data,data,c:\path1\folder2\folder3\folder4\...,data,data,data
フィルタは次のものを生成したいと思います。
data,data,c:\path1\folder2\folder3\,data,data,data
3番目の列には、1つのフォルダーから複数のフォルダーまでどこにでも配置できるファイルパスが含まれています。最大3つのフォルダを持ちたいです。
他の残りの列を削除したくなく、ファイルをその場で編集したいと思います。
awk
私は、、sed
コマンドcut
をステートメントcut -f1-4 -d '\'
に結合しようとしましたが、awk
一生の間それを動作させることはできません。
答え1
GNU awkを使用してgensub()を実行します。
$ awk -v n=3 'BEGIN{FS=OFS=","} {$3=gensub("(([^\\\\]*\\\\){"n+1"}).*","\\1",1,$3)} 1' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
または awk を使用してください。
$ awk -v n=3 'BEGIN{FS=OFS=","} match($3,"(([^\\\\]*\\\\){"n+1"})"){$3=substr($3,1,RLENGTH)} 1' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
答え2
sed
4つのバックスラッシュで区切られた文字列を含む他の古いフィールドがないとします。
$ sed 's/\(\([^,\]\{1,\}[\]\)\{4\}\)[^,]*/\1/' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
または拡張正規表現を使用して
$ sed -E 's/(([^,\]+[\]){4})[^,]*/\1/' file
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
data,data,c:\path1\folder2\folder3\,data,data,data
ここで使用される表現sed
は代替表現であり、置換されるテキストはそれと一致するものです(([^,\]+[\]){4})[^,]*
。この正規表現は、空でないバックスラッシュで区切られた4つの文字列(([^,\]+[\]){4}
)と一致してキャプチャします。これは代替文字列で再利用するためにキャプチャされますが、[^,]*
次のコンマを含むすべてのエントリ(末尾の一致が何でも)は削除されます。
代替テキストは、\1
挿入される4桁のバックスラッシュで区切られた文字列です。
cut
明らかにandを使用してこれを行うこともできますが、paste
次のコマンドはファイルを読み取るためにパイプされます。三回、3番目のフィールドのパス名から最後のバックスラッシュを削除します。
$ paste -d , <( cut -d , -f -2 file ) <( cut -d , -f 3 file | cut -d '\' -f -4 ) <( cut -d , -f 5- file )
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
最初の2つのフィールドを3番目のフィールドのパス名の一部として扱うことで最初のフィールドを削除できますが、これによりcut
ファイルを2回読み取ることができます。
$ paste -d , <( cut -d '\' -f -4 file ) <( cut -d , -f 5- file )
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
data,data,c:\path1\folder2\folder3,data,data
答え3
awk -F "\\" '{gsub(/\.*,/,",",$0);print $1"\\"$2"\\"$3"\\"$4$NF}' file.txt
data,data,c:\path1\folder2\folder3,data,data,data
data,data,c:\path1\folder2\folder3,data,data,data
data,data,c:\path1\folder2\folder3,data,data,data
data,data,c:\path1\folder2\folder3,data,data,data
Python
#!/usr/bin/python
import re
qw=re.compile(r'\.*')
k=open('file.txt','r')
for i in k:
respa=re.sub(qw,"",i.strip()).strip().split('\\')
print "{0}\\{1}\\{2}\\{3}{4}".format(respa[0],respa[1],respa[2],respa[3],respa[-1])
出力
data,data,c:\path1\folder2\folder3,data,data,data
data,data,c:\path1\folder2\folder3,data,data,data
data,data,c:\path1\folder2\folder3,data,data,data
data,data,c:\path1\folder2\folder3,data,data,data