我有两个csv文档,其中包含由GAM生成的Google Drive中的源和目标文件列表。一个名为copytoarchive.csv
,列出了源代码中的所有相关文件。另一个是alreadyinarchive.csv
,列出了目标中已经存在的所有相关文件。
Google云端硬盘的工作方式是为每个文件分配一个UID,而不管其名称如何。csv文件列表在一列中显示文件UID,在另一列中显示文件名。
以下是copytoarchive.csv
的示例:
Owner,id,name,Parent
user@domain.com,1gyKqu_P0h3j1Vn-6EwUv_99q,PreschoolExampleLessonName-20230504_050216-Meeting Recording.mp4,1b-U8XU0jYVFCggoEH9E9wqUm
user@domain.com,14-sg-qSnn5GDAuftANdLxDXp,OneonOneExampleLessonName-20230510_043228-Meeting Recording.mp4,1TtaABRvoki4gNuyqRrlyTfzj
user@domain.com,1L9mQBJ6d3DIPbiIEyV7akArV,OtherYearLevelExampleLessonName-20230510_033024-Meeting Recording.mp4,1CdiBgePlVqPvtcEp83DmcUrotr
user@domain.com,1oHaFzLF_KcgVX-hZn5etBka9,TeacherTrainingLesson-20230510_000950-Meeting Recording.mp4,1QusVD-a9U16I-0GTP1t-Vd9Ez
user@domain.com,1_ewCEh37sZYpqZlr3TC8u2Yl,ExampleStaffMeeting-20230509_045403-Meeting Recording.mp4,1tOb7xV5OCMMebn2ab2KdXGvc
user@domain.com,1SyXjINXttrb3VKvpbjpm1y-V,ExampleLessonName-20230503_052304-Meeting Recording.mp4,13g_fYh9HYtnDtd4psHEZi
以下是alreadyinarchive.csv
的外观:
Owner,id,name,Parent
user@domain.com,1Zlnhqf6fSxTRT2JEmQS91cCX,PreschoolExampleLessonName-20230504_050216-Meeting Recording.mp4,1CdiBgePlVqPvtcEp83DmcUro
user@domain.com,1Lg2W0w8YGJytSgJl2JblBly3,OtherYearLevelExampleLessonName-20230510_033024-Meeting Recording.mp4,1TtaABRvoki4gNuyqRrlyTfzj
user@domain.com,1Q_K0D1RgZlz-LMlDUVrV0gGi,ParentTrainingLesson-20230510_000950-Meeting Recording.mp4,1b-U8XU0jYVFCggoEH9E9wq
user@domain.com,1LIrRoTGtADjQRg9IRmIlJ3oV,ExampleStaffMeeting-20230509_045403-Meeting Recording.mp4,1xVuHbE3pcWN1l7X109qTsIYZK
user@domain.com,1OHkH9Cg7i2-O-ZHXBr4wIYGZ,OneonOneExampleLessonName-20230510_043228-Meeting Recording.mp4,1U7Y2Xh4Qi3atCcVL262
user@domain.com,1jZsXB5TT0H0TRrvvZu5A3N1S,DifferentLessonName-20230503_052614-Meeting Recording.mp4,1eVS3QF_Sk_6fQkwF8PvTKQf
“所有者”(Owner)和“父项”(Parent)字段中的数据与批处理文件的此部分无关。
如何在csv中搜索文件名字段(字段3)中的重复项,然后删除整个记录或仅输出字段3中不包含重复项的记录到新文件?
例如:
1.请注意,第一个非头记录copytoarchive.csv
的文件名与第一个非头记录alreadyinarchive.csv
的文件名相匹配,即使UID不同。这将被标记为重复。
1.还要注意,第二个非头记录copytoarchive.csv
中的文件名与第五个非头记录alreadyinarchive.csv
中的文件名相匹配,尽管UID不同。这也将被标记为重复。
1.此外,请注意,尽管copytoarchive.csv
的TeacherTrainingLesson...
(第4个非头记录)的时间戳与alreadyinarchive.csv
的ParentTrainingLesson...
(第3个非头记录)匹配,但由于文件名不完全匹配,因此不应将其视为重复。
在大约2,000条记录中,只有大约300条不是重复的。
如果需要,我很乐意将copytoarchive.csv
和alreadyinarchive.csv
操作到一个文件中。
起初,我试图通过嵌套的for /f
循环来实现这一点,其中第一个for /f
将一次读取copytoarchive.csv
的一行,并通过第二个嵌套的for /f
循环将相关标记(tokens=3
)与alreadyinarchive.csv
的每一行的相关标记进行比较。
根据要求,下面是我尝试的for /f
循环:
setlocal enabledelayedexpansion
rem This code block takes the info from copytoarchive.csv and alreadyinarchive.csv, deletes any matching lines (e.g., files already in the archive), and generates filestocopy.csv which contains the old and new parent IDs for only those files needing to be copied to the archive.
set /a filenum=0
set /a totalfiles=0
for /f "delims=, tokens=2-4" %%k in (C:\path\copytoarchive.csv) do (
set /a filenum+=1
set /a totalfiles+=1
call set fileID[!filenum!]=%%k
call set filename[!filenum!]=%%l
call :checkifexists
)
set oldfileID[1]=OldParent
set newparentID[1]=NewParent
if exist c:\path\filestocopy.csv del c:\path\filestocopy.csv
for /l %%q in (1,1,%totalfiles%) do (
echo !newowner[%%q]!,!newparentID[%%q]!,!oldfileID[%%q]!,!newparentname[%%q]! >> c:\path\filestocopy.csv
)
exit /b
:checkifexists
for /f "delims=, tokens=3" %%n in (C:\path\alreadyinarchive.csv) do (
if not !filename[%filenum%]!==%%n (
set fileparentID[%filenum%]=%%m
)
)
goto :eof
虽然这在技术上是可行的,因为每个列表几乎有2,000行长,这会产生大约400万次迭代,这需要太长的时间(在我的i9-12900 PC上超过10分钟)才能完成。请注意,这只是一个更大的批处理文件的一部分。
我读了findstr
,但我找不到一种方法来使用它只搜索一个字段。
我还安装了GNU CoreUtils,包括gawk
。阅读gawk
的PDF手册,似乎这可能是最好的路径,但我仍然在努力找到正确的参数传递给gawk
,让它只搜索“名称”字段。
我找到了@perl的答案here,它看起来非常接近一个解决方案,但我不知道如何将其转换为我的用例。
任何帮助都很感激。
2条答案
按热度按时间fnx2tebb1#
rem在应用于真实的数据之前,请始终根据测试目录进行验证。
代码中的注解解释了大部分内容。
神奇的是
!line:.mp4=?!
子句。line
中的.mp4
替换为?
。Batch无法子串
metavariables
行%%e
,因此必须将%%c
传输到用户变量(line
)以执行子串。需要line
的 * 当前 * 值,因此替换在delayedexpansion
模式下执行,因此格式为!var!
Stephan's DELAYEDEXPANSION link我使用
?
,因为它不能出现在文件名中。不清楚您是想要实际的输出行还是只想要文件名,所以我提供了两个行,它们之间用
?
分隔bq9c1y662#
嗯……首先,关于你的请求有几点意见:
UID
字段也是不相关的,重复的字段是基于文件名列的,所以你对UID
的描述让人困惑。for /f "delims=, tokens=2-4" %%k in ( ...
命令中包含逗号作为分隔符,但在您的文件中没有一个逗号!此外:echo !newowner[%%q]!,!newparentID[%%q]!,!oldfileID[%%q]!,!newparentname[%%q]!
表示输出字段由逗号分隔,没有空格...你 * 没有 * 描述也没有发布你的文件的 * 真实的 * 格式,尽管这在评论中被要求了几次...
由于所有这些原因,我假设你发布的文件格式不正确,正确的文件应该是这些文件:
copytoarchive.csv:
alreadyinarchive.csv:
这样的进程应该避免使用任何外部(
.exe
)命令(如findstr
或find
),以便运行得更快。环境变量足以解决这个问题:filestocopy.csv:
PS -你详细描述了不相关的数据,并没有描述足够的重要点...
:(