gpt4 book ai didi

node.js - 如何制作一个遍历所有 .m 和 .h 文件并替换这行代码的脚本

转载 作者:太空宇宙 更新时间:2023-11-04 03:19:27 24 4
gpt4 key购买 nike

我希望制作一个脚本,递归地遍历每个具有 .m 或 .h 扩展名的文件,然后查找此模式:

#import <React/ThisCanBeAnyText.h>

并将其替换为:

#if __has_include(<React/ThisCanBeAnyText.h>)
#import <React/ThisCanBeAnyText.h>
#else
#import "ThisCanBeAnyText.h"
#endif

ThisCanBeAnyText部分是最重要的,它可以是任何类型的文本。

脚本可以是 bash script ,或 node javascript script .

最佳答案

find ... -exec 组合非常有活力。如果您打算走这条路,那么编写一些代码,以便从 find 调用的命令会进行一些验证和错误检查,这样会更可靠。

下面演示了其中的一些内容,但请注意,您平台上的 bashsed 版本很重要:将换行符放入替换模式有时可能会成为一个障碍。

此脚本还会重新调用自身来包装 sed 的调用 - 这种技术有点可爱,但允许功能驻留在同一脚本中。

#!/bin/bash

set -e

main() {
if [[ "$#" -lt 2 ]]; then
echo "Usage: $0 <dir> <anytext>" 1>&2
exit 1
fi

# reinvoke this script, replacing directory name with '--',
# then perform the invoked seds with some care.

if [[ -d "$1" ]]; then
find "$1" -type f \( -name '*.m' -o -name '*.h' \) -exec "$0" -- "$2" {} +
elif [[ "$1" = '--' ]]; then
shift
do_seds "$@"
fi
}

do_seds() {
iname="$1"
shift

del=$'\a'
nl=$'\\\n'
frm="#import <React/$iname.h>"
to="#if __has_include(<React/$iname.h>)$nl #import <React/$iname.h>$nl#else$nl #import \"$iname.h\"$nl#endif"

for file; do
if sed "s$del^$frm\$$del$to$del" "$file" > "$file".$$; then
if cmp -s "$file" "$file".$$; then
# nothing changed; delete the new file
rm -f "$file".$$
else
# if chmod supports --reference, retain perms that way
chmod --reference="$file" "$file".$$
# leave the original file around, with ~ suffix
mv "$file" "$file"~
mv "$file".$$ "$file"
fi
else
echo "$file: failed to process" 1>&2
rm -f "$file".$$
fi

done
}

main "$@"

对于您的示例,如果上述内容在当前目录中保存为 do_subs 并使其可执行,则用法可能如下所示:

$ ./do_subs directory_with_hm_files ThisCanBeAnyText

回复评论

可以调整 sed“from”表达式(变量 frm)以包含正则表达式,以及通过“to”表达式中的反向引用使用匹配的 RE 内容。

如果您的 chmod 不支持 --reference 语法,只需将其删除即可。新版本接下来使用 umask 022 来创建公开可读的新文件。

调整后的脚本:

#!/bin/bash

set -e

main() {
if [[ "$#" -eq 1 ]] && [[ -d "$1" ]]; then
# only arg is a directory, launch the find command
find "$1" -type f \( -name '*.m' -o -name '*.h' \) -exec "$0" -- {} +
elif [[ "$#" -ge 2 ]] && [[ "$1" = '--' ]]; then
# two or more args, first is '--', means invoked by "find ... -exec"
shift
umask 022
do_seds "$@"
else
echo "Usage: $0 <dir>" 1>&2
exit 1
fi
}

do_seds() {
del=$'\a'
nl=$'\\\n'

# adjust RE in frm pattern as needed to match real content in .h and .m files

frm="#import <React/\\([a-zA-Z][a-zA-Z]*\\)\\.h>"
to="#if __has_include(<React/\\1.h>)$nl #import <React/\\1.h>$nl#else$nl #import \"\\1.h\"$nl#endif"

for file; do
if sed "s$del^$frm\$$del$to$del" "$file" > "$file".$$; then
if cmp -s "$file" "$file".$$; then
# nothing changed; delete the new file
rm -f "$file".$$
else
# leave the original file around, with ~ suffix
mv "$file" "$file"~
mv "$file".$$ "$file"
fi
else
echo "$file: failed to process" 1>&2
rm -f "$file".$$
fi
done
}

main "$@"

现在的用法变成:

$ ./do_subs directory_with_hm_files

关于node.js - 如何制作一个遍历所有 .m 和 .h 文件并替换这行代码的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51976910/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com