Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 批处理脚本,逐行读取选项卡分隔的文本文件,并将一列提取到新文件中_Arrays_Regex_Batch File_Sed_Substring - Fatal编程技术网

Arrays 批处理脚本,逐行读取选项卡分隔的文本文件,并将一列提取到新文件中

Arrays 批处理脚本,逐行读取选项卡分隔的文本文件,并将一列提取到新文件中,arrays,regex,batch-file,sed,substring,Arrays,Regex,Batch File,Sed,Substring,我有从iTunes播放列表导出的文本文件,这些列表是选项卡分隔的数组。它们有27列,但为了简单起见,我只在示例中包括四列: Name Artist My Rating Location Pod1 Show1 0 E:\Podcasts\Show1\Episode99.m4a Pod2 Show2 100 E:\Podcasts\Show2\Show2 Ep 101 - Subtitle.mp3 Pod3 Show2 6

我有从iTunes播放列表导出的文本文件,这些列表是选项卡分隔的数组。它们有27列,但为了简单起见,我只在示例中包括四列:

Name    Artist  My Rating   Location
Pod1    Show1   0           E:\Podcasts\Show1\Episode99.m4a
Pod2    Show2   100         E:\Podcasts\Show2\Show2 Ep 101 - Subtitle.mp3
Pod3    Show2   60          E:\Podcasts\Show2\News 11-17-2014.aicc
等等。我只需要提取位置(始终是最后一列)并将其放置在新的文本文件中,使其看起来像这样:

E:\Podcasts\Show1\Episode99.m4a
E:\Podcasts\Show2\Show2 Ep 101 - Subtitle.mp3
E:\Podcasts\Show2\News 11-17-2014.aicc
以下是我迄今为止为实现这一目标而编写的代码:

@ECHO OFF

type Podcasts.txt | findstr /v Grouping > Podcasts1.txt
del Podcasts.txt
rename Podcasts1.txt Podcasts.txt
虽然我找到了一些关于修改单行和逐行阅读文本文件的单独教程,但我甚至很难按照自己喜欢的方式修改单行,更不用说合并这两个原则了。我想这可能是一个非常快速的答案,我只是没有进行正确的搜索

我发现可以使用以下正则表达式在Notepad++中获得我想要的结果:

Find: .+(E\:)
Replace: \1
因此,在批处理脚本中逐行执行该操作的方法将非常有用

好处:我将生成的文件用作删除不在播放列表中的文件的白名单。如果你有一个链接或者可以快速编写一段代码,这会很有帮助。否则,我会想到如何计划完成这项工作,这将需要使用单个文件夹

编辑:我发现,由于某些列是空白的,因此使用以下方法:

for /f "usebackq tokens=1-26,* delims=  " %%a in ("Podcasts.txt") do (
   echo %%q >> PodcastsTest.txt
)
有时会打错方向。我需要一些东西,可以搜索两个字符“E:”并从那里开始行动,或者在查找第一个选项卡时从右向左搜索行

我刚刚创建的搜索反斜杠(当前仅显示在位置中)的快速脏方法如下所示:

for /f "usebackq tokens=1,* delims=\" %%a in ("Podcasts.txt") do (
    echo E:\%%b >> PodcastsTest.txt
) 
这不是一个安全的方法,因为没有任何东西可以阻止其他字段使用反斜杠,但作为一个临时解决方案,它可以工作

我发现了。也许有一种方法可以适应下面的Notepad++REGEX搜索

Find: .+(E\:)
Replace: \1

这是一个新的解决方案,基于源数据的限制和问题中添加的额外信息,以及接受使用其他工具:

call jrepl ".*(E:.*)" "$1" /i /f "Podcasts.txt" /o "Podcasts2.txt"
上面的代码使用名为
Jrepl.bat
(由dbenham编写)的本机Windows批处理脚本
jrepl.bat可从以下位置下载:
也可以在这里找到:

将其与批处理文件放在同一文件夹中,或放在系统路径上的文件夹中

第二部分

然后,可以使用下面的代码生成一个文件,其中列出了当前文件夹中的所有文件,这些文件不在由上面的jrepl代码生成的文件中

您提到的是单个文件夹,所以这就是它所处理的,并且可以在使用它来检查文件之前对其进行检查

事实上,如果文件名只在文件中出现一次,则可以将其用于原始源文件。

@echo off
(
for %%a in (*.*) do (
   if /i not "%%~nxa"=="%~nx0" if /i not "%%~nxa"=="Podcasts2.txt" find /i "\%%~nxa" < "Podcasts2.txt" >nul || echo del "%%a"
)
)>delfiles.bat.txt"

这是一个新的解决方案,基于源数据的限制和问题中添加的额外信息,以及接受使用其他工具:

call jrepl ".*(E:.*)" "$1" /i /f "Podcasts.txt" /o "Podcasts2.txt"
上面的代码使用名为
Jrepl.bat
(由dbenham编写)的本机Windows批处理脚本
jrepl.bat可从以下位置下载:
也可以在这里找到:

将其与批处理文件放在同一文件夹中,或放在系统路径上的文件夹中

第二部分

然后,可以使用下面的代码生成一个文件,其中列出了当前文件夹中的所有文件,这些文件不在由上面的jrepl代码生成的文件中

您提到的是单个文件夹,所以这就是它所处理的,并且可以在使用它来检查文件之前对其进行检查

事实上,如果文件名只在文件中出现一次,则可以将其用于原始源文件。

@echo off
(
for %%a in (*.*) do (
   if /i not "%%~nxa"=="%~nx0" if /i not "%%~nxa"=="Podcasts2.txt" find /i "\%%~nxa" < "Podcasts2.txt" >nul || echo del "%%a"
)
)>delfiles.bat.txt"

下面是一个纯批处理解决方案,它依赖于以下假设:所需位置始终以
E:\
开头(不区分大小写),并且该字符串不得出现在任何前面的列中:

@echo off
setlocal disableDelayedExpansion
>"Podcasts.txt.new" (
  for /f "usebackq skip=1 delims=" %%A in ("Podcasts.txt") do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo !ln:*E:\=E:\!
    endlocal
  )
)
如果您知道没有位置包含
,则只需在顶部启用一次延迟扩展,并从循环中删除SETLOCAL和ENDLOCAL

无论内容如何,正则表达式都是获取最后一列的好方法。一个很好的用于批处理的正则表达式实用程序是一个纯基于脚本的实用程序(混合JScript/batch),它从XP开始在任何Windows机器上本机运行

以下JREPL one衬里工作良好:

jrepl "[^\t]+$" $0 /jmatch /jbegln "skip=(ln==1)" /f "Podcasts.txt" /o "Podcasts.txt.new"
以下是另一个JREPL解决方案:

jrepl ".*\t" "" /a /jbegln "skip=(ln==1)" /f "Podcasts.txt" /o "Podcasts.txt.new"
注意-如果在批处理脚本中使用JREPL解决方案,则必须使用CALL JREPL

最后一个正则表达式可用于sed:

sed "1d;s/.*\t//" "Podcasts.txt" >"Podcasts.txt.new"

下面是一个纯批处理解决方案,它依赖于以下假设:所需位置始终以
E:\
开头(不区分大小写),并且该字符串不得出现在任何前面的列中:

@echo off
setlocal disableDelayedExpansion
>"Podcasts.txt.new" (
  for /f "usebackq skip=1 delims=" %%A in ("Podcasts.txt") do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo !ln:*E:\=E:\!
    endlocal
  )
)
如果您知道没有位置包含
,则只需在顶部启用一次延迟扩展,并从循环中删除SETLOCAL和ENDLOCAL

无论内容如何,正则表达式都是获取最后一列的好方法。一个很好的用于批处理的正则表达式实用程序是一个纯基于脚本的实用程序(混合JScript/batch),它从XP开始在任何Windows机器上本机运行

以下JREPL one衬里工作良好:

jrepl "[^\t]+$" $0 /jmatch /jbegln "skip=(ln==1)" /f "Podcasts.txt" /o "Podcasts.txt.new"
以下是另一个JREPL解决方案:

jrepl ".*\t" "" /a /jbegln "skip=(ln==1)" /f "Podcasts.txt" /o "Podcasts.txt.new"
注意-如果在批处理脚本中使用JREPL解决方案,则必须使用CALL JREPL

最后一个正则表达式可用于sed:

sed "1d;s/.*\t//" "Podcasts.txt" >"Podcasts.txt.new"

有sed和几个假设

PathTocygwin/sed -e '\#.*[[:blank:]]\([A-Z]:/.*$# !d' -e 's//\1/' Podcasts.txt > Podcasts1.txt
del Podcasts.txt
rename Podcasts1.txt Podcasts.txt
这里的假设 -路径正在使用映射驱动器 -在1到25列中没有以前的路径
-使用sed和几个假设只保留与模式对应的行

PathTocygwin/sed -e '\#.*[[:blank:]]\([A-Z]:/.*$# !d' -e 's//\1/' Podcasts.txt > Podcasts1.txt
del Podcasts.txt
rename Podcasts1.txt Podcasts.txt
这里的假设 -路径正在使用映射驱动器 -在1到25列中没有以前的路径 -仅保留与模式对应的行

可能重复的和其他发现的。在批处理文件中的
delims=
后指定一个水平制表符,并且FOR仅通过制表符instea分隔字段值