使用bash中的sed命令更改文件内容

13 浏览
0 Comments

使用bash中的sed命令更改文件内容

如何递归地在“/home/www/”目录树下的每个文本文件中查找并替换每个出现的子域名“subdomainA.example.com”为“subdomainB.example.com”?

0
0 Comments

在使用sed命令在bash中更改文件内容时,可能会遇到以下问题:如何排除.git子文件夹?

问题的原因是在使用sed命令更改文件内容时,如果应用于包含git仓库的文件夹,会改变.git文件夹中的内容,从而可能破坏git索引。

解决方法是在执行sed命令之前排除.git子文件夹。可以使用以下命令来实现:

grep -rl placeholder . | grep -Ev ".git" | xargs sed -i s/placeholder/lol/g

其中,grep -Ev命令用于排除匹配的模式,".git"表示排除包含.git的文件夹。在实际替换之前,可以先运行该命令进行测试,以便了解替换的效果,可以在不使用-i选项的情况下运行该命令,起到类似于干扰运行的作用。

在bash中使用sed命令更改文件内容时,如果涉及到包含git仓库的文件夹,需要注意排除.git子文件夹,以防止对git索引造成破坏。可以使用grep命令结合排除模式来实现对指定文件夹的内容替换。

0
0 Comments

在bash中使用sed更改文件内容的原因是希望批量替换文件中的文本。下面是一些问题的解决方法:

1. 对于不需要排除特定目录的情况,可以使用以下命令:

grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

2. 如果需要排除特定目录(如.svn),可以使用以下命令:

grep -rl oldtext . --exclude-dir=.svn | xargs sed -i 's/oldtext/newtext/g'

3. 在macOS上,使用`sed -i`命令会出现`sed: 1: "file_path": invalid command code .`错误,这是因为在macOS上`-i`是一个不同的标志。可以使用以下命令解决:

grep -rl old . | xargs sed -i "" -e 's/old/new/g'

4. 如果使用的是编译语言,并且不想检查二进制文件,可以使用以下命令添加`-I`标志:

grep -Irl oldtext . | xargs sed -i 's/oldtext/newtext/g'

5. 在git项目中,可以使用以下命令来避免搜索依赖项(这些依赖项可能在.gitignore中被忽略):

git grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

6. 如果文件名包含空格,上述命令将失败并显示`sed: can't read TOKEN: No such file or directory`错误。可以使用以下命令解决:

grep -rlZ oldtext . | xargs -0 sed -i 's/oldtext/newtext/g'

7. 另一个重要的方面是上述命令只会更新受影响文件的时间戳。

8. 对于macOS,可以使用以下命令来替代上述命令:

grep -rl oldtext . | xargs perl -pi -e 's/oldtext/newtext/g'

9. 如果不使用`grep --color=no ...`,可以使用以下命令:

grep --color=no -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'

10. 解决文件名包含空格的问题,可以更改xargs的分隔符为换行符:

grep -rl oldtext . | xargs -d '\n' sed -i 's/oldtext/newtext/g'

11. 在Windows 10上的VS Code的Git Bash终端中,可以使用以下命令来忽略隐藏文件/目录并捕获文件名中包含空格的文件:

grep -rl 'oldtext' * | xargs set -i 's/oldtext/newtext/g'

总结起来,以上是一些使用sed在bash中更改文件内容的问题和解决方法。这些方法可以帮助用户轻松地批量替换文件中的文本。

0
0 Comments

问题的出现原因:

需要在bash中使用sed命令来更改文件内容。具体的命令是通过find命令找到指定目录下的文件,并使用xargs命令将文件名作为参数传递给sed命令,然后使用sed命令来进行文件内容的替换。但是在执行过程中可能会出现一些问题。

解决方法:

1. 使用-print0选项告诉find命令将结果用null字符分隔,而不是换行符。这样做的好处是,如果目录中的文件名包含换行符,xargs命令仍然可以正确处理文件名。

2. 使用\( -type d -name .git -prune \)表达式完全跳过所有名为.git的目录。如果有其他要保留的文件夹(例如使用SVN),可以扩展这个表达式并匹配更多的名称。这个表达式相当于-not -path .git,但效率更高,因为它可以完全跳过目录而不是检查目录中的每个文件。之后的-o选项是因为-prune参数的工作方式。

3. 如果想要了解更多信息,请参考man find命令的文档。

这个方法对我有效,我在替换IP地址值时使用了这个方法。不过,有一个问题值得关注:为什么第一个subdomainA\.example\.com值中的点被转义,而第二个subdomainB.example.com值中的点没有被转义?我按照建议的格式执行了命令,并且看起来命令完美地完成了工作,但是我很好奇为什么只有第一个字符串模式中的点被转义。

如果文件中有一个不可修改的标志,这个脚本将在达到末尾之前停止,并显示"Permission denied"错误。建议使用-exec sed -i ... {} \;来代替管道。

我经常使用find . -type f -print0 | xargs -0 sed -i -e 's/\r$//'来在指定目录下递归地替换所有的CRLF为LF。

如果在MACOS中使用并且发现命令无效,可以尝试使用find命令的另一种格式:find . \( ! -regex '.*/\..*' \) -type f | LC_ALL=C xargs sed -i '' 's/foo/bar/g'。

(12年后,纪录一下)第一个URL中的点被转义是因为它在正则表达式的匹配文本中并且是特殊字符,但是第二个URL在替换文本中并且点在这个上下文中不是特殊字符。

0