我需要替换一个文件夹中的许多文件中的字符串,只有ssh访问服务器。我该怎么做呢?
当前回答
@kev的答案很好,但只影响直接目录中的文件。下面的示例使用grep递归地查找文件。这对我来说每次都很有效。
grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
命令分解
Grep -r:——recursive,递归地读取每个目录下的所有文件。 Grep -l:——print-with-matches,打印每个有匹配项的文件的名称,而不是打印匹配行。 Grep -i:——忽略大小写。
xargs:将STDIN转换为参数,遵循这个答案。 Xargs -i@ ~命令包含@~:一个占位符,用于~命令中特定位置的参数,@符号是一个占位符,可以被任何字符串替换。
Sed -i:就地编辑文件,不进行备份。 Sed /regexp/replace /:替换匹配regexp的字符串。 Sed s/regexp/replacement/g: global,对每个匹配进行替换,而不是仅对第一个匹配进行替换。
其他回答
这招对我很管用:
find ./ -type f -exec sed -i 's/string1/string2/' {} \;
sed -i 's/string1/string2/g' *。也许“foo”不是string1,“bar”不是string2。
为了维护我个人的英文节点,我写了一个实用程序脚本,帮助替换多对旧/新字符串,递归为一个目录下的所有文件。
新/旧字符串的多个对在一个散列映射中进行管理。
dir可以通过命令行或环境变量设置,映射是硬编码在脚本中,但如果需要,您可以修改代码从文件加载。
由于一些新特性,它需要bash 4.2。
en_standardize.sh:
#! /bin/bash
# (need bash 4.2+,)
#
# Standardize phonetic symbol of English.
#
# format:
# en_standardize.sh [<dir>]
#
# params:
# * dir
# target dir, optional,
# if not specified then use environment variable "$node_dir_en",
# if both not provided, then will not execute,
# *
#
paramCount=$#
# figure target dir,
if [ $paramCount -ge 1 ]; then # dir specified
echo -e "dir specified (in command):\n\t$1\n"
targetDir=$1
elif [[ -v node_dir_en ]]; then # environable set,
echo -e "dir specified (in environment vairable):\n\t$node_dir_en\n"
targetDir=$node_dir_en
else # environable not set,
echo "dir not specified, won't execute"
exit
fi
# check whether dir exists,
if [ -d $targetDir ]; then
cd $targetDir
else
echo -e "invalid dir location:\n\t$targetDir\n"
exit
fi
# initial map,
declare -A itemMap
itemMap=( ["ɪ"]="i" ["ː"]=":" ["ɜ"]="ə" ["ɒ"]="ɔ" ["ʊ"]="u" ["ɛ"]="e")
# print item maps,
echo 'maps:'
for key in "${!itemMap[@]}"; do
echo -e "\t$key\t->\t${itemMap[$key]}"
done
echo -e '\n'
# do replace,
for key in "${!itemMap[@]}"; do
grep -rli "$key" * | xargs -i@ sed -i "s/$key/${itemMap[$key]}/g" @
done
echo -e "\nDone."
exit
如果字符串中有正斜杠(/),则可以将分隔符更改为'+'。
find . -type f -exec sed -i 's+http://example.com+https://example.com+g' {} +
该命令将在当前目录中递归地运行。
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
出现的“foo”将被替换为“bar”。
在像macOS这样的BSD系统上,你需要提供一个备份扩展名,比如-i '.bak',否则每个manpage都会“冒损坏或部分内容的风险”。
cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *
有一个更简单的方法,使用一个简单的脚本文件:
# sudo chmod +x /bin/replace_string_files_present_dir
在gedit或你选择的编辑器中打开文件,我在这里使用gedit。
# sudo gedit /bin/replace_string_files_present_dir
然后在编辑器中将以下内容粘贴到文件中
#!/bin/bash
replace "oldstring" "newstring" -- *
replace "oldstring1" "newstring2" -- *
#add as many lines of replace as there are your strings to be replaced for
#example here i have two sets of strings to replace which are oldstring and
#oldstring1 so I use two replace lines.
保存文件,关闭gedit,然后退出您的终端,或者只是关闭它,然后启动它,以便能够加载您添加的新脚本。
导航到有多个要编辑的文件的目录。然后运行:
#replace_string_files_present_dir
按enter键,这将自动将包含它们的所有文件中的oldstring和oldstring1分别替换为正确的newstring和newstring1。
它将跳过不包含旧字符串的所有目录和文件。
如果您有多个目录的文件需要替换字符串,这可能有助于消除乏味的输入工作。你所要做的就是导航到这些目录,然后运行:
# replace_string_files_present_dir
你所要做的就是确保你已经包括或添加了所有替换字符串,就像我上面展示的那样:
替换 “oldstring” “newstring” -- *
在文件/bin/replace_string_files_present_dir的末尾。
要添加一个新的替换字符串,只需打开我们创建的脚本,在终端中输入以下命令:
Sudo gedit /bin/replace_string_files_present_dir
不要担心你添加的替换字符串的数量,如果没有找到oldstring,它们将没有任何影响。