【问题标题】:sed command creates randomly named filessed 命令创建随机命名的文件
【发布时间】:2011-12-05 17:50:10
【问题描述】:

我最近编写了一个执行 sed 命令的脚本,用于在名为“test.txt”的文件中将所有出现的“string1”替换为“string2”。

看起来像这样:

sed -i 's/string1/string2/g' test.txt

关键是,“string1”不一定存在于 test.txt 中。

我注意到在执行了一堆这些 sed 命令后,我得到了一些空文件,留在目录中,名称如下:

“sed4l4DpD”

有谁知道为什么会这样,我该如何纠正?

【问题讨论】:

  • 不使用-i选项时是否会发生这种情况?
  • 您不需要 -e 标志来将 s/.../.../g 参数视为脚本吗?
  • @okorz001:不,这里不需要-e 选项。
  • 这些文件的数量与您执行的 sed 命令的数量相比如何?它与包含或不包含“string1”的文件数量相比如何(我怀疑这无关紧要)。你在什么操作系统上? sed 是否报告失败(在 bash 中检查 $?,或在 tcsh 中检查 $status)?如果您有strace 命令,请尝试使用它:strace -o sed.strace sed ...;它将显示系统调用的参数和结果。查找失败的 write()rename() 呼叫。

标签: shell sed


【解决方案1】:

如果你这样做更好:

cat large_file | sed 's/string1/string2/g' > file_filtred

【讨论】:

  • cat 命令是不必要的。 sed 可以根据问题直接读取文件。更重要的是,此答​​案不会尝试回答所提出的实际问题。
【解决方案2】:

因此,经过昨晚的大量测试,事实证明 sed 在尝试对空字符串进行操作时创建了这些文件。我获取“$string1”参数数组的方式是通过 grep 命令,该命令似乎格式错误。我从 grep 中想要的是所有包含“Text here '.'”类型的行。

例如,文件中的字符串“Text here 'ABC.DEF'”应该已被 grep 捕获,然后字符串的 ABC.DEF 部分将被替换为 ABC_DEF。不幸的是,我使用的 grep 会捕获类型为“Text here ''”的行(即,'' 之间没有任何内容)。稍后,当脚本尝试使用这个空字符串执行 sed 替换时,随机文件被创建(可能是因为 sed 死了)。

感谢您在了解 sed 的工作原理方面提供的所有帮助。

【讨论】:

    【解决方案3】:

    -i 是赋予新/输出文件的后缀。此外,您需要 -e 来执行命令。
    使用方法如下:

    sed -i '2' -e 's/string1/string2/g' test.txt
    

    这将创建一个名为test.txt2 的文件,它是test.txt 的备份

    替换文件(而不是创建新副本 - 称为“就地”替换),请将 -i 值更改为 ''(即空白):

    sed -i '' -e 's/string1/string2/g' test.txt
    

    编辑二

    这是来自 Mac (Snow Leopard) 的实际命令行输出,显示我修改后的答案(删除了 -i 和后缀之间的空格)是正确的。
    注意:在 linux 服务器上,-i 和后缀之间不能有空格。

    > echo "this is a test" > test.txt
    > cat test.txt
    this is a test
    > sed -i '2' -e 's/a/a good/' test.txt 
    > ls test*
    test.txt    test.txt2
    > cat test.txt
    this is a good test
    > cat test.txt2
    this is a test
    > sed -i '' -e 's/a/a really/' test.txt 
    > ls test*
    test.txt    test.txt2
    > cat test.txt
    this is a really good test
    

    【讨论】:

    • 这不正确。 -i 的参数必须紧跟在 -i 之后;它不能是一个单独的论点。只需-i,文件就会就地更新(实际上;sed 在内部使用临时文件)。原始问题中的命令是正确的。它因未知原因而失败。 (我假设是 GNU sed,但它可能与其他 sed 实现相同。)
    • @Keith Thompson 请阅读更新。我能说什么...我是对的。
    • 你确定吗?对于 GNU sed(从 4.2.1 版开始),语法是 "-i[SUFFIX], --in-place[=SUFFIX]"; -i '' 甚至不起作用。在 Solaris 9 上,/usr/bin/sed 甚至没有 -i 选项。 POSIX 没有指定 -i 选项。您使用的是什么版本和操作系统?
    • 我看到 sed 的行为方式与您在 MacOS 上描述的方式相同;这是man page。但是你说这是一个“linux命令行输出”。你能澄清一下吗?
    • 是的,它是在 Mac 上完成的。我只是在我们的一台(真正的)Linux 服务器(GNU/Linux)上运行它,你是对的 - 它必须是 -i'2'(没有空格)。然后我在我的 Mac 上尝试了“无空间”版本,它也可以工作。也就是说,-i'2'-i '2'(无空格和有空格)在 Mac 上的工作方式相同
    【解决方案4】:

    我无法通过快速测试(使用 GNU sed 4.2.1)重现这一点——但 strace 确实显示 sed 创建了一个名为 sedJd9Cuy 的文件,然后将其重命名为 tmp(该文件名为命令行)。

    在 sed 创建临时文件之后,在它能够重命名它之前,似乎出现了问题。

    我的最佳猜测是您的文件系统空间不足;您可以创建一个新的空文件,但无法写入。

    df . 说什么?

    编辑

    我仍然不知道是什么导致了问题,但解决它应该不会太难。

    而不是

    sed -i 's/string1/string2/g' test.txt
    

    试试这样的:

    sed 's/string1/string2/g' test.txt > test.txt.$$ && mv -f test.txt.$$ test.txt
    

    sed 创建并重命名文本文件以替换原始文件的方式出现问题。上述命令使用 sed 作为简单的输入输出过滤器,并分别创建和重命名临时文件。

    【讨论】:

    • 运行 'df .'说我只使用了 8% 的空间(大约 150GB)。
    • stackoverflow.com/questions/1823591/… 看起来很相似。你在 Windows 上吗?
    • 该命令正在运行 Suse Linux 的服务器上运行。似乎命令正在成功执行,但是由于发生了大量替换,我很难确定(无需编写另一个脚本)。
    • 对于权限错误 就地替换,使用临时文件,请参阅stackoverflow.com/questions/20146239/…
    猜你喜欢
    • 2014-08-31
    • 2021-06-04
    • 1970-01-01
    • 2019-10-05
    • 2016-04-04
    • 2011-05-23
    • 2018-03-10
    • 2014-07-25
    • 1970-01-01
    相关资源
    最近更新 更多