如何使用命令行替换Linux中具有不同文件扩展名的多个子文件夹中的多个文件中的字符串
我已经关注了这个查询@ (如何在 Linux 命令行中替换多个文件中的字符串)。
我的问题是同样的问题的延伸。
我只想检查子文件夹中的特定文件扩展名,但不是每个文件扩展名。
我已经尝试过的:
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
我的问题:它也在其他所有文件格式中发生变化。我只想搜索并替换一个文件扩展名。
请添加另一个答案,我可以更改文件的整行,而不仅仅是一个单词。
提前致谢。
I have already followed this query @ (How to replace a string in multiple files in linux command line).
My question is rather an extension of the same.
I want to check only specific file extensions in the subfolders also but not every file extension.
What I have already tried:
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
My problem: It is changing in every other file format as well. I want to search and replace only in one file extension.
Please add another answer where I can change the entire line of a file as well not just one word.
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是有趣的单行命令解决方案,应该解决诸如您的
优点之类的问题:
一无法完全找到类似的解决方案,该解决方案可以在有关此主题的其他线程中同时执行上述所有
操作说明:
./
- 开始在当前目录中搜索。这可以替换为文件系统中的任何目录-type f
- 仅搜索文件(不是目录等)-print0
- 将空字符附加到每个文件的末尾找到的文件名。对于将输出通过管道传输到 xargs -0 非常重要xargs -0
- 将输入视为一系列以空字符结尾的字符串,并将其传递给下一个 grep 命令。这对于正确处理包含空格和特殊字符的文件名非常重要grep -l 'searchedString'
- 过滤输入文件以仅输出包含 searchedString 的文件名。 -l 导致输出仅包含文件名而不是文件中的匹配行,以便它们可以被接受作为 sedtee /dev/tty
的输入 - 这会将 grep 输出分叉到管道中的下一个命令,并且还可以到 /dev/tty 这是控制台窗口,以查看哪些文件将被更改。 (可选)可以将此信息写入某个日志文件,如下所示:... |三通 ~/replacement.log | tr ...
tr '\n' '\0'
- 默认情况下 grep -l 输出用换行符分隔的文件名。因此 tr 会对 xargs -0 输入的换行符进行翻译/替换为空字符,以避免空格/特殊字符问题sed -i
-i
参数告诉 sed 进行更改” in-place”,即修改作为参数提供的文件,而不仅仅是在控制台窗口中写入修改后的内容,而是's/searchedString/replacementString/g'
- s 代表替换/替换,g - 代表全局,即替换一行中的所有出现位置,而不仅仅是一行中的第一次出现示例:
在所有 .cpp 和 .c 文件中将所有出现的短语
parameter_extraction
替换为ParameterExtraction
但不是在文件名中附加 _old 的 .c、.cpp 文件,例如 test_old.cpp在查找表达式中:
-o
代表逻辑或-a
代表逻辑与注意:在表达式左括号 \( 和结束括号 \) 之前添加一个空格非常重要,否则会出现错误
您还询问如何更改文件中的整行,而不仅仅是一个短语
方法是使用修改后的 sed 命令
如果您想仅当输入行包含搜索短语时用新的不同行替换整行您可以使用不同语法的 sed
c - 代表 cut,即用 replacementString 代替包含 searchedString 的行
或者如果您想用新的不同行替换整个匹配行您可以使用正则表达式符号 ^ 和 $
^ - 表示下一个符号之前的行开始
$ - 表示前一个符号之后的行尾
因此整行可以与 ^line$ 正则表达式短语匹配
Here is interesting one-line command solution that should solve problems like Yours
Advantages:
I couldn't quite find a similar solution which does simultaneously all above in other threads on this topic
Explanation:
./
- start searching in current directory. This can be replaced by any directory in file system-type f
- search only for files (not directories, etc.)-print0
- append null character to the end of each found file name. Important for piping the output toxargs -0
xargs -0
- treat input as a serie of strings ending with null character and pass it to the next grep command. This is important to correctly handle file names with whitespaces and special charactersgrep -l 'searchedString'
- filter input files to output only file names that contain searchedString. -l causes output to contain only filenames instead of matched lines in files so that they can be accepted as input for sedtee /dev/tty
- this does the fork of grep output to next command in pipeline and also to /dev/tty which is the console window to see what files are going to be changed. Optionally can write this information to some log file instead like that:... | tee ~/replacement.log | tr ...
tr '\n' '\0'
- by default grep -l outputs file names separated with new lines. So tr does translation/replacement of newlines with null characters for input for xargs -0 to avoid whitespaces/special characters problemsed -i
-i
parameter tells sed to make changes "in-place", that is to modify files provided as argument not just write modified content in console window instead's/searchedString/replacementString/g'
- s stands for substitution/replacement, g - stands for global, that is replacing all occurrences in a line not only first occurrence in a lineExample:
replacing all occurrences of the phrase
parameter_extraction
withParameterExtraction
in all .cpp and .c files but not the .c, .cpp files that have been appended _old in the file names like test_old.cppIn find expressions:
-o
stands for logical or-a
stands for logical andnote: it is important to add a space after expression opening brackets \( and before ending brackets \) otherwise there will be an error
You also asked how to change the entire lines in a file, not just one phrase
The way to do that is to use modified sed command
If You want to replace whole lines with new different lines only when input lines contain the searched phrase You can use sed with different syntax
c - stands for cut, that is to put a replacementString in place of lines that contained searchedString
Or if You want to replace whole matched lines with new different lines You can use regex symbols ^ and $
^ - denotes start of the line before the next symbol
$ - denotes end of the line after the previous symbol
So whole lines can be matched with ^line$ regex phrase
最简单的解决方案是使用复杂的
grep
命令:grep -rli --include="*.html" --include=".json" '旧词' *
此解决方案的缺点。是您没有明确控制扫描哪些文件。
find
命令来查找所需的文件。使用 RegExp 过滤选项
-regex
来过滤文件名。因此,您验证扫描了正确的文件。
然后将
find
命令结果提供给grep
扫描列表。示例:
假设您正在查找文件扩展名
txt
pdf
html
。搜索路径从
/home/user/data
开始假设您找到文件后, 。可以通过
grep
匹配上述find
命令中的每个文件:Simplest solution is to use complex
grep
command:grep -rli --include="*.html" --include=".json" 'old-word' *
The disadvantage of this solution. Is that you do not have clear control which files are scanned.
find
command to locate your desired files.Using RegExp filtering option
-regex
to filter file names.So you verify the correct files are scanned.
Than feed the
find
command result togrep
scanning list.Example:
Assuming you are looking for file extensions
txt
pdf
html
.Assuming your search path begins in
/home/user/data
Once you have located your files. It is possible to
grep
match each file from the the abovefind
command:我希望有人会利用这条编码线,即使答案或解决方案太晚了。
这是始终适合我的命令行。
享受。 :)
I hope someone will take advantage of this coding line even if the answer or solution is too,late.
this is the command line that always works for me.
Enjoy. :)