How to replace a string in multiple files in linux

2019-01-07 01:49发布

I need to replace a string in a lot of files in a folder, with only ssh access to the server. How can I do this?

标签: linux string
22条回答
手持菜刀,她持情操
2楼-- · 2019-01-07 01:59

$ replace "From" "To" -- `find /path/to/folder -type f`

(replace - a string-replacement utility of MySQL Database System)

查看更多
We Are One
3楼-- · 2019-01-07 02:00

I found this one from another post (can't remember which) and while not the most elegant, it's simple and as a novice Linux user has given me no trouble

for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done

if you have spaces or other special characters use a \

for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done

for strings in sub-directories use **

for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
查看更多
forever°为你锁心
4楼-- · 2019-01-07 02:04

Really lame, but I couldn't get any of the sed commands to work right on OSX, so I did this dumb thing instead:

:%s/foo/bar/g
:wn

^- copy these three lines into my clipboard (yes, include the ending newline), then:

vi *

and hold down command-v until it says there's no files left.

Dumb...hacky...effective...

查看更多
放荡不羁爱自由
5楼-- · 2019-01-07 02:05

I did concoct my own solution before I found this question (and answers). I searched for different combinations of "replace" "several" and "xml," because that was my application, but did not find this particular one.

My problem: I had spring xml files with data for test cases, containing complex objects. A refactor on the java source code changed a lot of classes and did not apply to the xml data files. In order to save the test cases data, I needed to change all the class names in all the xml files, distributed across several directories. All while saving backup copies of the original xml files (although this was not a must, since version control would save me here).

I was looking for some combination of find + sed, because it worked for me in other situations, but not with several replacements at once.

Then I found ask ubuntu response and it helped me build my command line:

find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;

And it worked perfectly (well, my case had six different replacements). But please note that it will touch all *.xml files under current directory. Because of that, and if you are accountable to a version control system, you might want to filter first and only pass on to sed those actually having the strings you want; like:

find -name "*.xml" -exec grep -e "firstWord" -e "secondWord" -e "thirdWord" {} \; -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
查看更多
\"骚年 ilove
6楼-- · 2019-01-07 02:05

To maintain my personal English node, I wrote an utility script that help to replace multiple pair of old/new string, for all files under a directory recursively.

The multiple pair of old / new string are managed in a hash map.

The dir can be set via command line or environment variable, the map is hard coded in the script, but you can modify the code to load from a file, if necessary.

It requires bash 4.2, due to some new feature.

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
查看更多
叛逆
7楼-- · 2019-01-07 02:07

@kev's answer is good, but only affects files in the immediate directory.The example below uses grep to recursively find files. It works for me everytime.

grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @
查看更多
登录 后发表回答