【问题标题】:How to use each line of a file as an argument to a for loop如何使用文件的每一行作为 for 循环的参数
【发布时间】:2021-05-08 04:03:45
【问题描述】:

我希望对 foo.txt 中列出的每一行执行一个命令,其中 foo.txt 的每一行都是一个文件名。

这个问题得到了很多人的大力支持,并尝试了while readanother while read,我现在正在尝试做for loop。但是,我开始认为问题出在循环体中。

#!/bin/bash
File=/mnt/d/R_projects/EC/foo.txt
Lines=$(cat $File)
for Line in $Lines
do
    echo  "fastp -i /mnt/d/R_projects/EC/download/fastq/$Line -o /mnt/e/EC/fastp_trimmed/$Line"
   ./fastp -i /mnt/d/R_projects/EC/download/fastq/$Line -o /mnt/e/EC/fastp_trimmed/$Line
done

不幸的是,我收到了错误: 错误:无法打开文件:/mnt/d/R_projects/EC/download/fastq/SRR6132950_1.fastq

文件存在,并且执行less 确认。 奇怪的是,回声并没有回应我的期望,而是说: " -o /mnt/e/EC/fastp_trimmed/SRR6132950_1.fastqRR6132950_1.fastq"

什么可能导致此问题?好像前半段被剪掉了一样。

【问题讨论】:

  • Lines=$(cat $File) 是一个 UUOc不必要地使用 cat)。重定向是正确的方法。在你可以重定向一行并在for循环中逐行读取它之前,你需要将IFS设置为'\n'。然后你可以做for i in $(< somefile); do ...
  • 您的文件可能包含回车符(即 CRLF 而不是 LF),因为您从 Windows 复制、访问或编辑了它。删除它们;现有的问题有数百个。
  • 关于 DOS/Windows 文件(带有 CRLF 行结尾)的典型问题是:Are shell scripts sensitive to encoding and line endings? 您还可以在 while read 循环中修剪 CR(在 bash 中,但不是在所有其他 shell 中),使用while IFS=$'\r' read Line; do ... done <"$File"
  • 如果你正在处理回车字符,我希望你知道你可以使用dos2unix 命令? :-)

标签: bash for-loop


【解决方案1】:

谢谢大家,

我怀疑 Windows \r\n 在这里引起了问题,但我尝试在 nano 中删除这些并继续前进。 Notepad++ 显示了我的错误,并且能够通过 notepad++ 编辑>EOL 转换>Linux (LF) 进行修复。

我还调整了删除 cat 并添加 IFS 的建议 - suggestion 很有帮助。

#!/bin/bash
IFS=$'\n'
for Line in $(< /mnt/d/R_projects/EC/foo.txt); do
    echo  "$Line"
    echo  "fastp -i /mnt/d/R_projects/EC/download/fastq/$Line -o /mnt/e/EC/fastp_trimmed/$Line"
   ./fastp -i /mnt/d/R_projects/EC/download/fastq/$Line -o /mnt/e/EC/fastp_trimmed/$Line
done

我有大约一百万个基于文本文件运行命令的需求,这对于进一步的应用程序将非常有帮助。

【讨论】:

  • 如果任何行可以解释为 glob,这仍然不起作用,因为未引用的命令替换将经历文件名扩展和分词。 Use a while loop.
猜你喜欢
  • 2017-12-30
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多