我可以使用以下方式在一系列文本文件中添加前缀:
* PySpark is installed at c:\users\username\.conda\envs\dbconnect\lib\site-packages\pyspark
* Checking SPARK_HOME
* Checking java version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
* Skipping scala command test on Windows
* Testing python command
19/07/25 15:11:15 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Using Spark's default log4j profile: org/apache/spark/log4j-defaults.properties
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
19/07/25 15:11:17 WARN MetricsSystem: Using default name SparkStatusTracker for source because neither spark.metrics.namespace nor spark.app.id is set.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4040. Attempting port 4041.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4041. Attempting port 4042.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4042. Attempting port 4043.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4043. Attempting port 4044.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4044. Attempting port 4045.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4045. Attempting port 4046.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4046. Attempting port 4047.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4047. Attempting port 4048.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4048. Attempting port 4049.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4049. Attempting port 4050.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4050. Attempting port 4051.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4051. Attempting port 4052.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4052. Attempting port 4053.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4053. Attempting port 4054.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4054. Attempting port 4055.
19/07/25 15:11:17 WARN Utils: Service 'SparkUI' could not bind on port 4055. Attempting port 4056.
19/07/25 15:11:17 ERROR SparkUI: Failed to bind SparkUI
java.net.BindException: Address already in use: bind: Service 'SparkUI' failed after 16 retries (starting from 4040)! Consider explicitly setting the appropriate port for the service 'SparkUI' (for example spark.ui.port for SparkUI) to an available port or increasing spark.port.maxRetries.
这将变成
:: rename files
for %%a in (*.txt) do (
ren "%%a" "Seekret file %%a"
:: ECHO %%a Seekret file %%a
)
进入
a.txt
b.txt
c.txt
但是,上面的代码似乎用前缀将第一个文件重命名了两次。我最终得到
Seekret文件Seekret文件a.txt
我不知道为什么。有什么想法吗?
答案 0 :(得分:3)
使用
for /f "delims=" %%a in ('dir /b /a-d *.txt') do (
正在发生的事情是您使用的版本将重命名的文件视为新文件。 dir
版本构建文件名列表,然后然后在每一行执行for
,因此该列表已经构建并且是静态的,cmd
不是试图对移动的目标进行操作。
还-在代码块(带括号的指令序列)中不要使用rem
,而不能使用::
,因为这种形式的注释实际上是一个损坏的标签,{{1 }}。
答案 1 :(得分:3)
是的,这可能会发生,尤其是在FAT32和exFAT驱动器上,因为这些文件系统不会将通配符模式匹配的目录条目列表返回给按字母顺序调用可执行文件。 for
依次处理与*.txt
匹配的目录条目,命令ren
导致目录条目的更改,即文件名列表在迭代时被修改。
解决方案正在使用:
for /F "eol=| delims=" %%I in ('dir *.txt /A-D /B 2^>nul') do ren "%%I" "Seekret file %%I"
在这种情况下, FOR 在后台%ComSpec% /c
中运行,并在'
之间指定命令行,这意味着Windows安装在目录C:\ Windows:
C:\Windows\System32\cmd.exe /C dir *.txt /A-D /B 2>nul
因此,在后台启动了另一个命令过程,该过程执行 DIR ,其中
/A-D
(属性而不是目录)而仅用于文件/A-D-H
排除隐藏文件)*.txt
/B
,以纯格式输出文件名。DIR 输出的错误消息,用于处理 STDERR ,如果找不到与这些条件匹配的目录条目,则将其重定向到设备 NUL 来抑制该错误消息strong>。
阅读有关Using Command Redirection Operators的Microsoft文章,以获取2>nul
的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符>
必须在 FOR 命令行上使用脱字符号^
进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式dir
命令行。
没有路径的文件名由 DIR 输出,以处理后台命令过程的 STDOUT 。此输出分别由 FOR 和执行批处理文件的命令进程捕获。
启动命令过程本身终止后, FOR 处理捕获的文件名列表。由于这个原因,在循环迭代期间对目录所做的所有更改都不再重要。文件名列表不再更改。
即使以eol=| delims=
开头或包含空格字符,也需要选项I
来获得一个完整地分配给循环变量;
的文件名。 eol=|
将默认的行尾字符;
重新定义为任何文件名都不能包含的竖线。 delims=
定义了一个空的定界符列表,以禁用普通空格和水平制表符上的默认行拆分行为。
注意:::
是无效标签,不是注释。命令块内的标签是不允许的,通常会在执行命令块时导致未定义的行为。使用命令 REM (备注)进行注释。
更好的是:
for /F "eol=| delims=" %%I in ('dir *.txt /A-D /B 2^>nul ^| %SystemRoot%\System32\findstr.exe /B /I /L /V /C:"Seekret file "') do ren "%%I" "Seekret file %%I"
FINDSTR 在此处用于从 DIR 输出的文件名列表中输出,并重定向到 FINDSTR STDIN >所有文件名
/V
(倒置结果),/B
/I
/L
(对/C:
而言是多余的),因此将字面意思解释为Seekret file
。需要选项/C:
来指定包含两个空格的搜索字符串,因为仅使用"Seekret file"
会导致对Seekret
或file
进行字面且不区分大小写的搜索一行的开始。在仅用"..."
指定的搜索字符串中, FINDSTR 将每个空格解释为Perl正则表达式字符串中的|
之类的OR表达式。
用/C:
指定的搜索字符串被隐式解释为文字字符串,但是使用/R
(而不是/L
),可以将该字符串解释为正则表达式字符串在其上,空格被解释为空格而不是OR表达式。可以使用多次/C:
指定多个搜索字符串。
我对使用 FINDSTR 的建议:始终使用/L
或/R
来明确表示 FINDSTR 和命令的每个读者一行 FINDSTR 应该如何解释用"..."
或/C:"..."
指定的搜索字符串。
答案 2 :(得分:1)
我想我也要戴上帽子,因为我并不真正喜欢遍历dir
输出,而且目前没有人认为这个脚本已经运行:
@echo off
set "dir=C:\Your\Root\Directory"
set "pfx=Seekret file "
setlocal enabledelayedexpansion
for /r "%dir%" %%A in (*.txt) do (
set "txt=%%~nA"
if not "!txt:~0,13!"=="%pfx%" ren "%%A" "%pfx%%%~nxA"
)
pause
for /r
将循环遍历所有.txt文件,将每个文件设置为参数%%A
(每次迭代),将变量txt
设置为参数%%A
,减少为其名称(%%~nA
),然后将文本文件的前13个字符与示例前缀(在包含空格Seekret file
时为13个字符)进行比较-如果它们与循环匹配什么也没做;如果它们不匹配,则循环将重命名%%A
以在开头包含前缀。如果您不希望它是递归的,则可以改用for %%A in ("%dir%"\*.txt) do (
。除此之外,您只需要更改!txt:~0,13!
即可,具体取决于您的前缀是什么或要检查的文件名中有多少个字母。您也不必设置目录和前缀变量,我只是喜欢这样做,因为它使块看起来更整洁-而且更容易返回并更改一个值,而不是在脚本中该值出现的每个位置。