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