如何遍历目录中的文件并更改路径并为文件名添加后缀

我需要编写一个脚本,用不同的参数启动我的程序,但我是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 for
end for

所以我真的很困惑如何从第一个参数创建第二个参数,所以看起来dataABCD_Log1.txt并开始我的程序。

1156704 次浏览
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##*/}替换(壳参数展开)删除了直到最后一个/的前导路径名。

base=${name%.txt}替换删除尾随的.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中文本文件的路径(包括 /Data/部分)
  • $( ... )运行shell命令并在命令行中的该点插入其输出
  • basename somepath .txt输出Somepath的基本部分,从末尾删除. txt(例如/Data/file.txt->file

如果您需要使用Data/file.txt而不是/Data/file.txt运行MyProgram,请使用"${filename#/}"删除前导斜杠。另一方面,如果您要扫描的真的是Data而不是/Data,请使用for filename in Data/*.txt

很抱歉对线程进行了死灵编程,但是每当您通过全局化遍历文件时,最好避免全局不匹配的角落情况(这会使循环变量扩展为(不匹配的)全局模式字符串本身)。

例如:

for filename in Data/*.txt; do
[ -e "$filename" ] || continue
# ... rest of the loop body
done

参考:巴什陷阱

看起来您正在尝试执行一个windows文件(. exe)当然您应该使用Powershell。无论如何,在Linuxbash shell上,一个简单的一行就足够了。

[/home/$] for filename in /Data/*.txt; do for i in {0..3}; do ./MyProgam.exe  Data/filenameLogs/$filename_log$i.txt; done done

或者在狂欢中

#!/bin/bash


for filename in /Data/*.txt;
do
for i in {0..3};
do ./MyProgam.exe Data/filename.txt Logs/$filename_log$i.txt;
done
done

您可以使用带有read的查找空分隔输出选项来安全地遍历目录结构。

#!/bin/bash
find . -type f -print0 | while IFS= read -r -d $'\0' file;
do echo "$file" ;
done

所以你的案子

#!/bin/bash
find . -maxdepth 1 -type f  -print0 | while IFS= read -r -d $'\0' file; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$file" 'Logs/'"`basename "$file"`""$i"'.txt'
done
done

此外

#!/bin/bash
while IFS= read -r -d $'\0' 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)

将在脚本(进程)的当前范围内运行if循环,并允许在需要时使用查找的输出来设置变量

对每个文件运行命令

对所有. txt文件执行某些操作(回声)

for f in *.txt;  do echo ${f}; done;