批处理文件:将两列的字符串组合到另一列中
Posted
技术标签:
【中文标题】批处理文件:将两列的字符串组合到另一列中【英文标题】:Batch file: Combine string of two columns in another column 【发布时间】:2020-12-08 14:52:22 【问题描述】:我目前正在尝试自动化我的 csv 数据的预处理过程。 我的 csv 表如下所示:
id; town; nrlanes; direction; name; x; y; edgeid;
129001; Wales; 1; Scottland; Scottland B10; 54529; 338288; E332;
111002; Wales; 2; London; London B12; 54529; 338288; E304;
334003; Wales; 3; Ireland; Ireland B3; 54529; 338288; E303;
我想要做的是用列 id(最后 3 位数字应该被剪掉!)和方向(+ 字符串“Ri.”应该放在前面的组合来覆盖列“name”)方向)。结果表应如下所示:
id; town; nrlanes; direction; name; x; y; edgeid;
129001; Wales; 1; Scottland; 129 Ri. Scottland; 54529; 338288; E332;
111002; Wales; 2; London; 111 Ri. London; 54529; 338288; E304;
334003; Wales; 3; Ireland; 334 Ri. Ireland; 54529; 338288; E303;
这是我迄今为止尝试过的:
@echo off
REM for /f "tokens=1,2,3,4,5,6,7,8 delims=;" %%a in (%PREPROCESSING_OUTPUT_PATH%temp.csv) do echo %%a;%%b;%%c;%%d;%%~a Ri. %%~d;%%e;%%f;%%g >> "%PREPROCESSING_OUTPUT_PATH%%OUTPUT_FILENAME%"
(
for /F "tokens=1-8* delims=;" %%a in (%PREPROCESSING_OUTPUT_PATH%temp.csv) do (
set id=%%a
set id_cut=%id:~-3%
set merged_columns=%id_cut% Ri. %%~d
echo %%a;%%b;%%c;%%d;%%e;%merged_columns%;%%f;%%g
)
)>> "%PREPROCESSING_OUTPUT_PATH%%OUTPUT_FILENAME%"
我在另一个线程中读到 %var_name:~-3% 削减了字符串的最后三位数字,这正是我所需要的。 这是我的bat文件版本的结果:
id; town; nrlanes; direction; ; x; y; edgeid;
129001; Wales; 1; Scottland; ; 54529; 338288; E332;
111002; Wales; 2; London; ; 54529; 338288; E304;
334003; Wales; 3; Ireland; ; 54529; 338288; E303;
如您所见,“name”列为空,“name”列也为空。我在这里做错了什么?有什么建议吗?
【问题讨论】:
我用的是windows,bat文件是通过命令行执行的 在@echo off
之后执行setlocal enabledelayedexpansion
然后将set id_cut=%id:~-3%
更改为set id_cut=!id:~-3!
并将echo %%a;%%b;%%c;%%d;%%e;%merged_columns%;%%f;%%g
更改为echo %%a;%%b;%%c;%%d;%%e;!merged_columns!;%%f;%%g
不,不要在你的问题中改变它,在你的脚本中改变它。
@Gerhard 嘿,我用你的建议更新了我的问题,但解决方案并不完全是想要的。缺少 id,列名不应更改为“Ri. direction”(应保持“名称”)。
好的,让我快速看看这个。
【参考方案1】:
你需要delayedexpansion
请注意,我必须将 %
替换为 !
以扩展变量,这些变量在括号循环中是 set
。我还假设您没有所有空格?
@echo off
setlocal enabledelayedexpansion
(for /F "skip=1 tokens=1-6* delims=;" %%a in (%PREPROCESSING_OUTPUT_PATH%temp.csv) do (
set "id=%%a"
echo %%a;%%b;%%c;%%d;!id:~0,-3! Ri. %%~d;%%f;%%g
)
)>"%PREPROCESSING_OUTPUT_PATH%%OUTPUT_FILENAME%"
最后,考虑一下你的结果会对标题做什么,如果不需要,你需要skip=1
,然后修改标题以满足你的需要。这是一个保留原始标题的示例:
@echo off
setlocal enabledelayedexpansion
for /F "delims=" %%a in (%PREPROCESSING_OUTPUT_PATH%temp.csv) do (
(echo %%a)>"%PREPROCESSING_OUTPUT_PATH%%OUTPUT_FILENAME%" & goto :file
)
:file
(for /F "skip=1 tokens=1-6* delims=;" %%a in (%PREPROCESSING_OUTPUT_PATH%temp.csv) do (
set "id=%%a"
echo %%a;%%b;%%c;%%d;!id:~0,-3! Ri. %%~d;%%f;%%g
)
)>>"%PREPROCESSING_OUTPUT_PATH%%OUTPUT_FILENAME%"
【讨论】:
你为什么要拆分标题然后重新组装它而不改变它,为什么不简单地将它保留为单个标记?for /F "tokens=* delims=;" %%a in …
。或者,您可以这样做:< "%PREPROCESSING_OUTPUT_PATH%temp.csv" set /P head=
,然后是 > "%PREPROCESSING_OUTPUT_PATH%%OUTPUT_FILENAME%" echo(%head%
...
@aschipfl,谢谢,是的。当我创建答案并进行编辑时,我有点复制了原始的 for 循环。再次感谢。
嘿格哈德,不知何故,这个解决方案不会将列的标题打印到输出文件中。关于如何解决这个问题的任何想法?
第二个例子就是这样做的。它将按原样提取标题,然后循环将进行操作。您能在代码中显示您所做的更改吗?以上是关于批处理文件:将两列的字符串组合到另一列中的主要内容,如果未能解决你的问题,请参考以下文章