【问题标题】:Bash - output to loop using findBash - 使用 find 循环输出
【发布时间】:2016-07-26 08:37:50
【问题描述】:

我有一个文件列表(files.txt):

file1.txt
file2.txt
file3.txt

当我执行时:

cat files.txt | while read line; do find -name $line >> outfile.txt; done

为什么我没有得到包含这些文件路径列表的输出文件?

如果我执行:

find -name file1.txt >> outfile.txt

任务完成

非常感谢

克莱夫

【问题讨论】:

  • 您是否在 Windows 机器上编辑了files.txt,然后将其复制到 unix 或 linux 服务器,而不将行尾从 DOS 格式转换?请检查od -c files.txt | head 的输出,如果不清楚您在看什么,请将其附加到您的问题中。哦,确保你引用你的变量。未加引号的变量中的特殊字符会导致不可预知的结果!
  • 嗨@ghoti,是的,谢谢。如何转换行尾?
  • 已回答,如下。享受! :)
  • @user3329732 附带说明。你真的应该让你的脚本首先创建一个文件数组并将该数组传递给find,所以它只需要做一个。否则,您将多次遍历同一棵树。

标签: bash loops find


【解决方案1】:

显然您在 Windows 机器上编辑了files.txt,然后将其复制到您的 Linux 或 Unix 服务器,而不转换行尾。这不是一个不常见的问题,并且存在多种解决方案。 :)

Windows 使用 CR+LF (\r\n) 换行,而 unix 和 linux 仅使用 LF (\n)。

如果您的复制程序支持这样的事情,第一个也是最简单的选择可能是重新复制文件并进行适当的转换。如果您使用 FTP 协议复制文件,请检查您的客户端是否有“类型”选项,该选项可能设置为“ascii”或“bin”。取决于你的客户。如果你使用像scp 这样的东西,它只传输二进制文件,那么请继续阅读。

另一个经过验证的选项是使用dos2unix 应用程序,它可能已经安装在您的 unix 或 linux 服务器上。如果不是,您可以使用机器的包管理器安装它。 (我不知道怎么做,因为你没有提到你正在使用什么操作系统。)如果安装,可以通过运行man dos2unix 找到使用dos2unix 的文档。例如,如果你想转换当前目录下所有匹配*.txt的文本文件以及当前目录下的所有子目录,你可以使用如下:

find . -type f -name \*.txt -exec dos2unix -k -o {} \;

这里起作用的选项如下:

  • find . - 告诉 find 从当前目录开始递归搜索。
  • -type f -name \*.txt 按文件类型和 glob 限制我们的搜索。
  • -exec 在每个文件上运行该行的其余部分,直到 \;,并将 {} 替换为文件名。
  • dos2unix - 嗯,你知道的。
  • -k - “保留”原始文件的时间戳。
  • -o - 编辑“原始”文件而不是编写新文件。

如果 dos2unix 不可用,许多其他内置工具可能能够完成类似的工作。

如果您运行的是 Linux,则可以像这样在一个文件上使用 GNU sed:

sed -i 's/\r$//' files.txt

或者处理当前目录下的所有文本文件:

for file in *.txt; do sed -i 's/\r$//' "$file"; done

如果您使用的是 bash 版本 4 或更高版本,或者以递归方式运行:

shopt -s globstar
for file in **/*.txt; do sed -i 's/\r$//' "$file"; done

转换行尾的另一种选择可能是 perl:

perl -pi -e 's/\r\n/\n/g' files.txt

如果需要,您可以轻松地使其处理一个目录中的多个文件,或者以与上述选项类似的方式递归处理。

另一种选择可能是保留文件原样,并在 bash 中处理 files.txt 时进行转换。例如:

while read line; do
    find . -name "${line%$'\r'}" 
done < files.txt > outfile.txt

这使用 shell 的参数扩展与 bash 的格式扩展相结合,在您的 while 循环读取每个变量时“剥离”有问题的 CR 字符。


还要注意:

【讨论】:

  • 不客气!如果这解决了您的问题,请随时单击答案左侧的绿色复选标记关闭问题。
猜你喜欢
  • 2017-06-15
  • 2014-07-08
  • 2018-02-20
  • 2013-09-11
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 2015-11-08
  • 2019-02-17
相关资源
最近更新 更多