首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在CSV文件中修剪路径名

在CSV文件中修剪路径名
EN

Unix & Linux用户
提问于 2022-02-10 21:35:51
回答 3查看 109关注 0票数 -1

在第三次或第九次出现字符\之后,我试图在CSV的一个特定列中修剪数据。

我的数据如下所示:

代码语言:javascript
复制
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

我想让过滤器产生:

代码语言:javascript
复制
data,data,c:\path1\folder2\folder3\,data,data,data

第三列包含一个文件路径,它可能位于从一个文件夹到多个文件夹的任意位置。我希望有一个最多3个文件夹。

我不想删除其他的列,但编辑文件到位。

我一直在尝试使用awksed,并试图将cut命令cut -f1-4 -d '\'组合成一个awk语句,但在我的一生中无法让它发挥作用。

EN

回答 3

Unix & Linux用户

回答已采纳

发布于 2022-02-14 08:43:38

代码语言:javascript
复制
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

代码语言:javascript
复制
#!/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])

输出

代码语言:javascript
复制
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
票数 0
EN

Unix & Linux用户

发布于 2022-02-10 21:56:37

使用GNU awk for gensub():

代码语言:javascript
复制
$ 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

或用任何一只头巾:

代码语言:javascript
复制
$ 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
票数 1
EN

Unix & Linux用户

发布于 2022-02-10 22:19:12

使用sed,假设其他早期字段不包含由四个反斜杠分隔的字符串:

代码语言:javascript
复制
$ 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

或者,使用扩展的正则表达式,

代码语言:javascript
复制
$ 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})。这是为了在替换字符串中重新使用而捕获的,但是直到并包含下一个逗号的所有内容(无论后面的[^,]*匹配什么)都会被丢弃。

替换文本是\1,它插入这四位反斜杠分隔的字符串。

显然,您也可以使用cutpaste来完成这一任务,但是请注意,下面的命令管道读取文件三次,并在第三个字段中删除路径名上的最后反斜杠:

代码语言:javascript
复制
$ 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,但是它仍然读取文件两次:

代码语言:javascript
复制
$ 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
票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/690147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档