我需要替换一个文件夹中的许多文件中的字符串,只有ssh访问服务器。我该怎么做呢?


当前回答

我给出了一个修复python源代码中常见shebang错误的示例。

您可以尝试grep/sed方法。下面是一个适用于GNU sed并且不会破坏git回购的程序:

$ grep -rli --exclude '*.git*' '#!/usr/bin/python' . | xargs -I {} \
gsed -i '' -e 's/#!\/usr\/bin\/python/#!\/usr\/bin\/env python/' {}

或者你可以使用greptile:)

$ greptile -x .py -l -i -g '#!/usr/bin/env python' -r '#!/usr/bin/python' .

我刚刚测试了第一个脚本,第二个脚本应该也可以工作。小心转义字符,我认为在大多数情况下使用greptile应该更容易。当然,您可以使用sed做许多有趣的事情,为此,最好与xargs一起使用sed。

其他回答

假设你想搜索字符串search,并在多个文件中使用replace替换它,这是我久经考验的一行公式:

grep -RiIl 'search' | xargs sed -i 's/search/replace/g'

grep的快速解释:

- r -递归搜索 -i不区分大小写 - i -跳过二进制文件(你想要文本,对吗?) -l输出一个简单的列表。其他命令需要

然后将grep输出通过管道传输到sed(通过xargs),后者用于实际替换文本。-i标志将直接修改文件。把它移开,进行一种“演练”模式。

在MacBook Pro上,我使用了以下方法(灵感来自https://stackoverflow.com/a/19457213/6169225):)

sed -i '' -e 's/<STR_TO_REPLACE>/<REPLACEMENT_STR>/g' *

-i "将确保您没有备份。 -e表示现代正则表达式。

为了维护我个人的英文节点,我写了一个实用程序脚本,帮助替换多对旧/新字符串,递归为一个目录下的所有文件。

新/旧字符串的多个对在一个散列映射中进行管理。

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

要替换文件中的路径(避免转义字符),您可以使用以下命令:

sed -i 's@old_path@new_path@g'

@符号意味着在接下来的字符串中所有的特殊字符都应该被忽略。

类似于Kaspar的答案,但是用g标记来替换一行上的所有出现。

find ./ -type f -exec sed -i 's/old_string/new_string/g' {} \;

对于全局不区分大小写:

find ./ -type f -exec sed -i 's/old_string/new_string/gI' {} \;