以下命令正在更改2个文件的内容.
sed -i 's/abc/xyz/g' xaa1 xab1
Run Code Online (Sandbox Code Playgroud)
但我需要做的是动态更改几个这样的文件,我不知道文件名.我想编写一个命令,它将从当前目录开始读取所有文件,xa*并且sed应该更改文件内容.
eal*_*nso 142
我很惊讶没有人提到查找的-exec参数,它适用于这种用例,尽管它会为每个匹配的文件名启动一个进程:
find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} \;
Run Code Online (Sandbox Code Playgroud)
或者,可以使用xargs,这将调用更少的进程:
find . -type f -name 'xa*' | xargs sed -i 's/asd/dsg/g'
Run Code Online (Sandbox Code Playgroud)
或者更简单地使用+ exec变体而不是;find来允许find为每个子进程调用提供多个文件:
find . -type f -name 'xa*' -exec sed -i 's/asd/dsg/g' {} +
Run Code Online (Sandbox Code Playgroud)
len*_*nik 125
更好的是:
for i in xa*; do
sed -i 's/asd/dfg/g' $i
done
Run Code Online (Sandbox Code Playgroud)
因为没有人知道有多少文件,并且很容易打破命令行限制.
以下是文件太多时会发生的情况:
# grep -c aaa *
-bash: /bin/grep: Argument list too long
# for i in *; do grep -c aaa $i; done
0
... (output skipped)
#
Run Code Online (Sandbox Code Playgroud)
Raj*_*Raj 77
你可以一起使用grep和sed.这允许您递归搜索子目录.
Linux: grep -r -l <old> * | xargs sed -i 's/<old>/<new>/g'
OS X: grep -r -l <old> * | xargs sed -i '' 's/<old>/<new>/g'
For grep:
-r recursively searches subdirectories
-l prints file names that contain matches
For sed:
-i extension (Note: An argument needs to be provided on OS X)
Run Code Online (Sandbox Code Playgroud)
fun*_*oll 28
这些命令不适sed用于Mac OS X附带的默认设置.
来自man 1 sed:
-i extension
Edit files in-place, saving backups with the specified
extension. If a zero-length extension is given, no backup
will be saved. It is not recommended to give a zero-length
extension when in-place editing files, as you risk corruption
or partial content in situations where disk space is exhausted, etc.
Run Code Online (Sandbox Code Playgroud)
试着
sed -i '.bak' 's/old/new/g' logfile*
Run Code Online (Sandbox Code Playgroud)
和
for i in logfile*; do sed -i '.bak' 's/old/new/g' $i; done
Run Code Online (Sandbox Code Playgroud)
两者都很好.
pal*_*wim 15
@PaulR将此作为评论发布,但人们应将其视为答案(此答案最适合我的需求):
sed -i 's/abc/xyz/g' xa*
Run Code Online (Sandbox Code Playgroud)
这适用于适量的文件,可能大约为数十,但可能不是数百万.
另一种更通用的方法是使用find:
sed -i 's/asd/dsg/g' $(find . -type f -name 'xa*')
Run Code Online (Sandbox Code Playgroud)
小智 5
我正在用于find类似的任务。这很简单:你必须将它作为参数传递,sed如下所示:
sed -i 's/EXPRESSION/REPLACEMENT/g' `find -name "FILE.REGEX"`
这样你就不必编写复杂的循环,而且很容易看出,你要更改哪些文件,只需在find运行之前运行即可sed。