3

背景

我希望在发送之前# TODO从一些 python 源代码文件输出中删除任何注释。git archive我希望通过将在各种 *nix 操作系统上运行的脚本来执行此操作,因此它应该尽可能符合 POSIX。

我知道find -print0并且xargs -0不在基本规范中,但它们似乎很常见,我可以很好地使用它们(除非存在更好的替代方案)。ed由于sed -i不在就地编辑的基本规范中,我正在使用它。假设下面的命令是从一个已经解压的 git 存档的目录中运行的。

我很高兴有一个整体的替代解决方案来# TODO删除评论,但为了满足我的好奇心,我还想回答我在我提出的命令中面临的特定问题。

现有代码

find . -type f -name "*.py" -print0 | xargs -0 -I {} ed -s {} << 'EOF'
,g/^[ \t]*#[ \t]*TODO/d
,s/[ \t]*#[ \t]*TODO//
w
EOF

预期结果

所有以“.py”结尾的文件都被删除了仅包含 TODO 注释或以 TODO 开头的行尾注释的完整行。

实际结果

(标准输出)

,g/^[ \t]*#[ \t]*TODO/d
,s/[ \t]*#[ \t]*TODO//
w
: No such file or directory

当前理论

我相信<< 'EOF'heredoc 被应用于xargs而不是ed,我不知道如何解决这个问题。

4

1 回答 1

1

修复<< 'EOF'heredoc 方向需要一些sh -c技巧,最终导致更多问题,所以我尝试重新解决问题,而不需要heredoc。

我最终登陆:

inline() {
    # Ensure a file was provided
    in="${1?No input file specified}"
    # Create a temp file location
    tmp="$(mktemp /tmp/tmp.XXXXXXXXXX)"
    # Preserve the original file's permissions
    cp -p "$in" "$tmp"
    # Make $@ be the original command
    shift
    # Send original file contents to stdin, output to temp file
    "$@" < "$in" > "$tmp"
    # Move modified temp file to original location, with permissions and all
    mv -f "$tmp" "$in"
}

find . -type f -name "*.py" -exec grep -ilE '#[ \t]*TODO' {} \+ | while read file; do
    inline "$file" sed -e '/^[ \t]*#[ \t]*TODO/ d' -e 's/[ \t]*#[ \t]*TODO//'
done

mktemp在技​​术上不在基本规范中,但似乎相当便携,所以我很好包括它。ed也给我带来了一些问题,所以我回到sed了一个自定义函数来复制不可用-i标志以进行就地操作。

于 2015-05-04T17:37:32.527 回答