如何用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陷阱