我有一个文件列表(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
执行任务
非常感谢
克里夫
答案 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字符。
另外值得注意的是: