首页 文章

如何使用Bash迭代目录中的文件?

提问于
浏览
364

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

所以我真的很困惑如何从第一个创建第二个参数,所以它看起来像dataABCD_Log1.txt并启动我的程序 . 非常感谢帮助 .

附:我知道那里有类似的问题,但我没有发现创建我的日志文件名称 .

5 回答

  • 0

    看起来你正在尝试执行一个Windows文件(.exe)当然你应该使用PowerShell . 无论如何,在一个Linux bash shell上,一个简单的单行程就足够了 .

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

    或者在bash中

    #!/bin/bash
    
    for filename in `ls /Data/*.txt`; 
       do
         for i in {0..3}; 
           do ./MyProgam.exe Data/filename.txt Logs/$filename_log$i.txt; 
         done 
     done
    
  • -1

    我用来避免额外的线条或支票的东西:

    #!/bin/bash
    for filename in $(find /Data/*.txt 2> /dev/null); do
        for ((i=0; i<=3; i++)); do
            ./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
        done
    done
    

    这个想法是在子shell中运行find并将错误发送到/ dev / null,这样你就不会遍历关于丢失文件的错误 .

  • 471

    首先注意几个注意事项:当你使用 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 / part)

    • $( ... ) 运行shell命令并在命令行中的该点插入其输出

    • basename somepath .txt 输出somepath的基本部分,从末尾删除.txt(例如 /Data/file.txt - > file

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

  • 59

    很抱歉对线程进行了修改,但是每当你通过globbing迭代文件时,最好避免使用glob不匹配的极端情况(这会使循环变量扩展为(不匹配)glob模式字符串本身) .

    例如:

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

    参考:Bash Pitfalls

  • 175
    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 parameter expansion)删除前导路径名直到最后 / .

    base=${name%.txt} 替换删除尾随 .txt . 如果扩展可以变化,这有点棘手 .

相关问题