CSV 파일의 경로 이름 자르기

CSV 파일의 경로 이름 자르기

세 번째 또는 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개의 폴더를 갖고 싶습니다.

다른 나머지 열을 삭제하고 싶지 않고 파일을 제자리에서 편집하고 싶습니다.

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

sed4개의 백슬래시로 구분된 문자열이 포함된 다른 이전 필드가 없다고 가정하고 를 사용합니다 .

$ 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다음 명령은 파일을 읽기 위해 파이프됩니다.세 번, 세 번째 필드의 경로 이름에서 마지막 백슬래시를 제거합니다.

$ 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

처음 두 필드를 세 번째 필드의 경로 이름의 일부로 처리하여 첫 번째 필드를 제거할 수 있지만 cut이렇게 하면 여전히 파일을 두 번 읽습니다.

$ 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

파이썬

#!/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

관련 정보