Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.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
Powershell 如何批量检测文件名中的字符串?_Powershell_Batch File - Fatal编程技术网

Powershell 如何批量检测文件名中的字符串?

Powershell 如何批量检测文件名中的字符串?,powershell,batch-file,Powershell,Batch File,我正在尝试将包含数千个公司文档的一系列文件夹按字母顺序排序,并使用命名方案“姓氏,名”将单个文件夹列表排序 我试图排序的文档在文件名中有其主题的名称。例如,一个文件可以称为“Baggins\u Frodo\u Resume”或“Snow,Jon-Resume”。我需要将这些文件分别排序到名为“Snow,John”和“Baggins,Frodo”的文件夹中 我在名为“list of names.txt”的文本文件中有每个文件夹的名称,格式如下: Last First Baggins Frodo S

我正在尝试将包含数千个公司文档的一系列文件夹按字母顺序排序,并使用命名方案“姓氏,名”将单个文件夹列表排序

我试图排序的文档在文件名中有其主题的名称。例如,一个文件可以称为“
Baggins\u Frodo\u Resume
”或“
Snow,Jon-Resume
”。我需要将这些文件分别排序到名为“
Snow,John
”和“
Baggins,Frodo
”的文件夹中

我在名为“list of names.txt”的文本文件中有每个文件夹的名称,格式如下:

Last First
Baggins Frodo
Snow Jon

用简单的英语写出来,我想让批处理文件遵循下面概述的步骤。我在应该是变量的术语周围使用了括号

  • 读取文件“
    名称列表.txt
    ”中的第一行

  • 将列表中的姓氏指定给变量[last name],将名字指定给变量[first name]

  • 在目录[C:\需要排序的文件夹]中

  • 如果[file name]包含文本[last name]和[first name],则

  • 将[文件]复制到名为[姓,名]的文件夹中

  • 重复此操作,直到不再存在包含该名称的文件

  • 转到“list of names.txt”的下一行并重复

  • 我为我的错误代码提前道歉,当我需要批处理时,我通常只能勉强理解批处理的基本原理,但这次我真的很挣扎

    这里有几个问题,我非常感谢您的帮助

  • 正如我的问题所暗示的那样,我不确定如何只搜索每个文件的名称来查找匹配项,而不是搜索文件的全部内容

  • 此外,我不知道如何将名字/姓氏从“list of names.txt”中分离出来,以便将它们分配给单独的变量

  • 这是我关于stackoverflow的第一篇文章,在将来,我希望能够正确地调整代码的颜色。我在帮助部分看到“在许多情况下,语法突出显示语言将从问题的标记中推断出来”,但在我的案例中没有出现这种情况。我有什么明显的遗漏吗


  • 提前谢谢你的时间,我真的很感激

    我可以为您提供不同的方法吗

    @echo off
    setlocal EnableDelayedExpansion
    
    rem Within directory [C:\folder that needs sorting]...
    cd "C:\folder that needs sorting"
    
    rem Process the list of folder names. Note that %%a=Last and %%b=First
    rem Note that "usebackq" option is needed because the file name is enclosed in quotes
    for /F "usebackq tokens=1,2" %%a in ("C:\folder\of\list of names.txt") do (
    
       rem Move all file names with the name scheme "Last*First*.*" into "Last, First" folder
       move "%%a*%%b*.*" "C:\base\folder\of\%%a, %%b"
    
    )
    

    由于您已将其标记为
    powershell
    ,因此我假设您对使用它的解决方案持开放态度。此代码以CSV文件的形式读取
    名称列表.txt
    文件,然后迭代目录中的文件以查看是否存在匹配项。如果有,它会将文件移动到新目录。当您确信将创建正确的目录并适当移动文件时,
    mkdir
    Move Item
    命令中删除
    -WhatIf

    $thedir = 'C:\src\t\nc\files'
    $newdir = 'C:\src\t\nc\new'
    $listfile = 'list of names.txt'
    $thefiles = Get-ChildItem -File -Path $thedir
    
    Import-Csv -Path (Join-Path -Path $thedir -ChildPath $listfile) -Delimiter ' ' |
        ForEach-Object {
            foreach ($file in $thefiles) {
                if (($file.Name -match $_.Last) -and ($file.Name -match $_.First) -and ($file.Name -ne $listfile)) {
                    $dirname = $_.Last + ', ' + $_.first
                    $newpath = Join-Path -Path $newdir -ChildPath $dirname
                    if (-not (Test-Path -Path $newpath)) { mkdir -Path $newpath -WhatIf }
                    Move-Item -Path $file.fullname -Destination $newpath -WhatIf
                }
            }
        }
    
    @ECHO关闭
    SETLOCAL ENABLEDELAYEDEXPANSION
    设置“sourcedir=U:\sourcedir”
    设置“destdir=U:\destdir”
    设置“filename1=%sourcedir%\q56380365.txt”
    设置/a maxwords=0
    名称文件中每行的rem…到%%a
    对于/f“usebackqdelims=“%%a IN”(“%filename1%”)DO(
    快速眼动分析线
    呼叫:单词%%a
    如果!字数!lss 0转到:EOF
    IF!wordcount!gtr!maxwords!SET/a maxwords=!wordcount!
    )
    ::现在在maxwords中添加max#words
    :斯堪的纳维亚
    名称文件中每行的rem…到%%a
    对于/f“usebackqdelims=“%%a IN”(“%filename1%”)DO(
    这行有多少字?
    呼叫:单词%%a
    IF!wordcount!相等%maxwords%(
    rem使用找到的第一个字作为筛选器读取整个源目录
    对于/f“delims=“%%h IN('dir/b/a-d”%sourcedir%\!\1!*“2^>nul”)执行以下操作(
    调用:匹配名称“%%h”
    )
    )
    )
    设置/a maxwords-=1
    如果%maxwords%gtr 0转到scandir
    后藤:EOF
    ::建立“字数”并将字数设置为#*;细分
    字体文字
    呼叫:清除#
    SET/a字数=0
    设置“allwords=%~1%~2”
    设置“subdir=%~1”
    设置“细分2=%~2”
    ::如果提供的字数超过2个,则出错
    如果第%*&SET/a行出现“%~3”neq”回显错误,则wordcount=-1&GOTO:EOF
    :wordloop
    SET/a字数+=1
    呼叫:atom%allwords%
    设置“#%wordcount%=%car%”
    如果定义了cdr,则设置“allwords=%cdr%”并转到wordloop
    后藤:EOF
    ::第一个字到car,其余的字到cdr
    :原子
    设置“汽车=%1”
    设置“cdr=”
    :atomlp
    移位
    如果“%1”neq“设置”cdr=%cdr%%1“&转到atomlp
    如果已定义cdr,则设置“cdr=%cdr:~1%”
    后藤:EOF
    ::删除开始时的变量#
    :清除#
    对于%%b IN(#)DO For/F“delims=”%%a IN('set%%b 2^>Nul')DO set“%%a=”
    后藤:EOF
    ::将%1中的文件名与#*中的%maxwords%字匹配,如果匹配则移动
    :matchname
    设置“文件=%~1”
    设置/匹配=1
    ::将逗号、下划线[etc]替换为空格
    设置“文件=%file:,=%”
    设置“文件=%file:\=%”
    :匹配循环
    调用:atom%文件%
    如果/i“%car%”“neq”!#%match%”转到:EOF
    设置“文件=%cdr%”
    如果%match%neq%maxwords%SET/a match+=1&转到matchloop
    ::所有匹配-移动
    MD“%destdir%\%subdir%,%subdir2%”2>NUL>NUL
    回显移动“%sourcedir%\%~1”%destdir%\%subdir%,%subdir2%
    后藤:eof
    
    比我想象的要复杂一些。由于使用了
    delayedexpansion
    ,因此通常会出现有关
    等特殊字符的警告
    &
    以及其他非字母数字应仔细处理。正常的字母数字和逗号应该可以

    这种方法首先检查我的系统上的名称文件-
    q56380365.txt
    。它不仅允许两个名称,还允许一个带引号的字符串,因此可以使用像“van der Waals”Johannes这样的行。每一行都被传递到
    :words
    例程,该例程为子目录结构建立
    子目录和
    子目录2
    ,并对单个单词进行计数,并将它们放入环境变量
    #1
    #2
    #n
    。如果传递给
    :words
    的字符串超过2个,则它将
    wordcount
    返回为-1,以在报告行内容后标记错误。这样可以确保名称的两个部分被正确识别。
    $thedir = 'C:\src\t\nc\files'
    $newdir = 'C:\src\t\nc\new'
    $listfile = 'list of names.txt'
    $thefiles = Get-ChildItem -File -Path $thedir
    
    Import-Csv -Path (Join-Path -Path $thedir -ChildPath $listfile) -Delimiter ' ' |
        ForEach-Object {
            foreach ($file in $thefiles) {
                if (($file.Name -match $_.Last) -and ($file.Name -match $_.First) -and ($file.Name -ne $listfile)) {
                    $dirname = $_.Last + ', ' + $_.first
                    $newpath = Join-Path -Path $newdir -ChildPath $dirname
                    if (-not (Test-Path -Path $newpath)) { mkdir -Path $newpath -WhatIf }
                    Move-Item -Path $file.fullname -Destination $newpath -WhatIf
                }
            }
        }