如何用Bash迭代目录中的文件?
我需要编写一个脚本,用不同的参数来启动我的程序,但我是Bash的新手。 我开始我的程序是这样的:
./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 if end for
所以我真的很困惑如何从第一个参数创build第二个参数,所以它看起来像dataABCD_Log1.txt并启动我的程序。 非常感谢帮助。
PS我知道那里有类似的问题,但我没有发现什么创build我的日志文件名称。
首先要注意Data/data1.txt :当你使用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/*.txt展开到/ Data中的文本文件的path( 包括 / Data / part) -
$( ... )运行一个shell命令,并在命令行中input它的输出 -
basename somepath .txt输出/Data/file.txt的基础部分,从末尾删除.txt(例如/Data/file.txt– >file)
如果您需要使用Data/file.txt而不是/Data/file.txt运行MyProgram,请使用"${filename#/}"删除前导斜杠。 另一方面,如果它真的是你想要扫描的Data not /Data ,只需要for filename in Data/*.txt使用for filename in Data/*.txt 。
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##*/}replace( shell参数扩展 )会将前导path名删除到最后一个/ 。
base=${name%.txt}replace删除尾随.txt 。 如果扩展名可能有所不同,那有点麻烦。
对于necromancing线程抱歉,但是每当通过globbing迭代文件时,最好避免glob不匹配的情况(这会使循环variables扩展到(不匹配)glob模式string本身)。
例如:
for file in Data/*.txt; do [ -e "$file" ] || continue # ... rest of the loop body done
参考: Bash陷阱