./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt]
。这是我要执行的操作的伪代码:
for each filename in /Data do
for int i = 0, i = 3, i++
./MyProgram.exe Data/filename.txt Logs/filename_Log{i}.txt
end for
end for
所以我真的很困惑如何从第一个参数创建第二个参数,因此看起来像dataABCD_Log1.txt并启动我的程序。
#1 楼
首先要注意以下几点:当使用Data/data1.txt
作为参数时,它真的应该是/Data/data1.txt
(带斜杠)吗?另外,外循环应仅扫描.txt文件还是/ Data中的所有文件?这是一个答案,假设仅/Data/data1.txt
和.txt文件:#!/bin/bash
for filename in /Data/*.txt; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done
注意: / Data(包括/ Data /部分)中文本文件的路径
/Data/*.txt
运行shell命令,并将其输出插入命令行中的该点输出somepath的基部,并从结尾删除.txt(例如,
$( ... )
-> basename somepath .txt
)如果需要使用
/Data/file.txt
而不是file
运行MyProgram,请使用Data/file.txt
删除前导斜杠。另一方面,如果要扫描的确实是/Data/file.txt
而不是"${filename#/}"
,请使用Data
。#2 楼
很抱歉,该线程无法正常使用,但是每当您通过遍历遍历文件时,都应避免在这种情况下避免遍历不匹配的情况(这会使循环变量扩展为(不匹配的)遍历模式字符串本身)。 br />例如:
for filename in Data/*.txt; do
[ -e "$filename" ] || continue
# ... rest of the loop body
done
参考:重击陷阱
评论
这仍然是及时的警告。我以为自己创建的脚本不正确,但是我的文件扩展名是小写而不是大写,没有找到文件,并返回了glob模式。啊。
– RufusVS
17年9月14日在21:13
由于使用了Bash标记:这就是shopt nullglob的目的! (或也可以使用shopt failglob,具体取决于您想要的行为)。
– gniourf_gniourf
17年12月18日在17:46
此外,这还在循环到达之前检查在处理期间删除的文件。
–loxaxs
18年1月1日在22:26
还可以处理您拥有名为dir.txt的目录的情况
– vidstige
18年5月3日在23:41
#3 楼
for file in Data/*.txt
do
for ((i = 0; i < 3; i++))
do
name=${file##*/}
base=${name%.txt}
./MyProgram.exe "$file" Logs/"${base}_Log$i.txt"
done
done
name=${file##*/}
替换(shell参数扩展)将删除最后一个/
的前导路径名。如果扩展名可以变化,这会有些棘手。评论
我相信您的代码中有错误。一行应该是base = $ {name%.txt},而不是base = $ {base%.txt}。
–caseklim
14年5月15日在1:16
@CaseyKlimkowsky:是的;当代码和注释不一致时,至少其中之一是错误的。在这种情况下,我认为它只是一个代码。通常,实际上两者都是错误的。感谢您指出了这一点;我已经解决了。
–乔纳森·莱弗勒(Jonathan Leffler)
14年5月15日在1:21
除了使用name = $ {file ## * /}之外,您还可以使用name =`basename $ file`
– Tk421
10月18日23:08
#4 楼
您可以将finds null分隔的输出选项与read一起使用,以安全地遍历目录结构。#!/bin/bash
find . -type f -print0 | while IFS= read -r -d $'#!/bin/bash
find . -maxdepth 1 -type f -print0 | while IFS= read -r -d $'#!/bin/bash
while IFS= read -r -d $'q4312078q' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done < <(find . -maxdepth 1 -type f -print0)
' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done
' file;
do echo "$file" ;
done
因此,对于您而言
>
q4312078q
将在脚本的当前作用域(进程)中运行while循环,并允许将find的输出用于设置变量如果需要
评论
$'\ 0'是一种怪异的书写方式“”。您缺少IFS =,并且-r切换为read:您的read语句应为:IFS = read -rd”文件。
– gniourf_gniourf
19年2月8日在11:31
我认为有些需要搜索$'\ 0'并在其中散布一些堆栈点。进行您指出的编辑。没有IFS =尝试echo -e“ ok \ nok \ 0”的不良影响是什么?同时读取-d''行;做echo -e“ $ line”;完成似乎没有任何。另外,我看到的-r通常是默认设置,但是找不到防止它发生的示例。
–詹姆斯
19年2月9日在22:56
如果文件名以空格结尾,则需要IFS =:请尝试触摸“ Prospero”(注意尾随空格)。另外,如果文件名带有反斜杠,则需要使用-r开关:触摸“ Prospero \ n”来尝试使用它。
– gniourf_gniourf
19年2月9日在23:02
被低估的答案。在包含超过100k文件的目录中尝试获得最高支持的文件。如果您使用的是低端计算机,请祝您好运。
–五彩纸屑
6月14日8:10
#5 楼
看起来您正在尝试执行Windows文件(.exe),当然应该使用powershell。无论如何,在Linux bash shell上,一个简单的单行代码就足够了。在bash中或者在bash中
评论
显然,基名-s是非标准扩展名-我将编辑答案以使用标准语法。
–戈登·戴维森(Gordon Davisson)
13年12月27日在16:23
如果未找到/匹配任何文件,则我发现for循环执行块的通配符仍然使用filename =“ /Data/*.txt”输入一次。如何避免这种情况?
–奥利弗·皮尔曼(Oliver Pearmain)
2015年2月3日,15:22
@OliverPearmain可以在循环之前使用shopt -s nullglob(在以后使用shopt -u nullglob以避免以后出现问题),或者添加[[! -e“ $ filename]];然后继续;在循环开始时执行fi,因此它将跳过不存在的文件。
–戈登·戴维森(Gordon Davisson)
15年2月3日,19:01
当某些文件名称中包含空格时,这将不起作用。
–伊莎·哈森(Isa Hassen)
16年1月24日在20:29
@Isa只要所有的双引号都到位,它就应该与空白一起使用。忽略任何双引号,您将遇到空格问题。
–戈登·戴维森(Gordon Davisson)
16年1月25日,0:01