8

我在一个目录中有一堆 xml 文件,需要对它们执行 dos2unix 命令,并且每隔一段时间就会添加新文件。我不是每次都想用脚本自动执行每个文件时手动执行 dos2unix 命令。在我的生活中,我什至从未看过一个 shell 脚本,但到目前为止,我从一些教程中读到了这个:

FILES=/tmp/testFiles/*
for f in $FILES
do
  fname=`basename $f`
  dos2unix *.xml $f $fname
done

但是,我不断显示“使用”输出。我认为问题在于我没有正确分配新文件的名称(fname)。

4

4 回答 4

8

您收到使用消息的原因是它dos2unix不接受您提供的额外参数。但是,它将接受多个文件名(也通过 glob)。除非您正在处理的文件多于命令行可以接受的文件,否则您不需要循环。

dos2unix /tmp/testFiles/*.xml

应该是你所需要的,除非你需要递归:

find /tmp/testFiles -name '*.xml' -exec dos2unix {} +

(对于 GNU 查找)

于 2012-07-02T11:31:11.597 回答
2

如果所有文件都在一个目录中(不需要递归),那么你就快到了。

for file in /tmp/testFiles/*.xml ; do
    dos2unix "$file"
done

默认情况下dos2unix应就地转换并覆盖原始文件。

如果需要递归,您还必须使用find

find /tmp/testFiles -name '*.xml' -print0 | while IFS= read -d '' file ; do
    dos2unix "$file"
done

.xml这将适用于所有以in结尾的文件/tmp/testFiles/及其所有子目录。

如果不需要其他步骤,您可以完全跳过 shell 循环:

非递归:

find /tmp/testFiles -maxdepth 1 -name '*.xml' -exec dos2unix {} +

对于递归:

find /tmp/testFiles -name '*.xml' -exec dos2unix {} +

在您的原始命令中,我看到您找到每个文件名的基本名称并尝试将其传递给dos2unix,但您的意图尚不清楚。后来,在评论中,您说您只想覆盖文件。我的解决方案执行转换,不创建备份并用转换后的版本覆盖原始版本。我希望这是你的意图。

于 2012-07-02T11:22:25.413 回答
1
mkdir /tmp/testFiles/converted/
for f in /tmp/testFiles/*.xml
do
  fname=`basename $f`
  dos2unix $f ${f/testFiles\//testFiles\/converted\/}
  # or for pure sh:
  # dos2unix $f $(echo $f | sed s@testFiles/@testFiles/converted/@)
done

结果将保存在converted/子目录中。

构造${f/testFiles\//testFiles\/converted\/}(感谢Rush)或sed在这里用于converted/在文件名之前添加:

$ echo /tmp/testFiles/1.xml | sed s@testFiles/@testFiles/converted/@
/tmp/testFiles/converted/1.xml
于 2012-07-02T10:43:09.563 回答
-1

目前尚不清楚您使用的是哪个 dos2unix 实现。不同的实现需要不同的参数。周围有许多不同的实现。

在 RedHat/Fedora/Suse Linux 上,您只需键入

    dos2unix /tmp/testFiles/*.xml

在 SunOS 上,您需要提供输入和输出文件名,上述命令会破坏您的几个文件。

于 2012-12-23T09:31:08.353 回答