Bash - 使用find输出到循环

时间:2016-04-06 06:00:04

标签: bash loops find

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

file1.txt
file2.txt
file3.txt

执行时:

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

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

然而,如果我执行:

find -name file1.txt >> outfile.txt

执行任务

非常感谢

克里夫

1 个答案:

答案 0 :(得分:0)

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

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

如果您的复制程序支持此类操作,则第一个也可能是最简单的选项可能是使用适当的转换重新复制文件。如果您使用FTP协议复制文件,请检查客户端是否输入"类型"选项,可以设置为" ascii"或" bin"。取决于您的客户。如果您正在使用仅传输二进制文件的scp之类的内容,请继续阅读。

另一个经过验证的选项是使用可能已安装在unix或linux服务器上的dos2unix应用程序。如果不是,您可以使用机器的包管理器进行安装。 (我不知道怎么做,因为您还没有提到您正在使用的操作系统。)如果已安装,可以通过运行dos2unix找到使用man 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的格式扩展到&#34; strip&#34;从while循环中读取的每个变量末尾的违规CR字符。

另外值得注意的是: