我需要替換文件夾中很多文件中的字符串,只有ssh
才能訪問服務器。我怎樣才能做到這一點?如何在linux命令行中替換多個文件中的字符串
回答
cd /path/to/your/folder
sed -i 's/foo/bar/g' *
「foo」的出現將被替換爲「bar」。
這爲我工作:
find ./ -type f -exec sed -i 's/string1/string2/' {} \;
Howerver,這並不:sed -i 's/string1/string2/g' *
。也許「foo」並不意味着是string1和「bar」而不是string2。
這是因爲sed以不同的方式處理通配符* [abc] *表示集合中的任意數量的字符{a,b ,c}。[a-z0-9] *的作用類似於通配符*。 – thepiercingarrow 2016-03-17 00:19:03
@ kev的回答很好,但隻影響直接目錄中的文件。下面的示例使用grep遞歸查找文件。它每次都適合我。
grep -rli 'old-word' * | xargs [email protected] sed -i 's/old-word/new-word/g' @
這對我不起作用,但是這樣做: 'grep --include = {* .php,*。html,* .js } -rnl'./'-e「old-word」| xargs -i @ sed -i's/old-word/new-word/g'@' – Dennis 2014-03-05 22:20:16
@pymarco你能解釋一下這個命令嗎?我不知道爲什麼你必須使用xargs而不是'''之後使用sed,還有,爲什麼'-i'在xargs命令中?我在手冊中讀過它,而不應該使用'-I'。用'@'作爲模式開始和結束的分隔符? – 2015-11-09 14:57:29
'sed沒有輸入文件',不能正常工作 – 2016-08-29 13:46:16
與Kaspar的答案類似,但用g標誌替換一行中的所有事件。
find ./ -type f -exec sed -i 's/string1/string2/g' {} \;
對於全球不區分大小寫:
find ./ -type f -exec sed -i 's/string1/string2/gI' {} \;
如果你在OSX上並且你的模式可能包含點並且你想要就地替換(沒有備份文件),你應該使用' LC_ALL = C find ./ -type f -exec sed -i''-e's/proc.priv/priv/g'{} \;'(參見[這篇文章])(http://stackoverflow.com/questions/19456518/invalid-command-code-though-escaping-periods-using-sed)和[this one](http://stackoverflow.com/questions/19242275/re-error-illegal-byte-sequence-on-mac -os-x)) – Sheljohn 2015-08-13 15:01:19
這對我來說絕對有效,因爲它可以使用-name「* .js」' – 2016-02-17 11:30:03
進行過濾詳細選項將很酷,但是您可以重新grep以查看是否進行了更改。注意:對於通配符,嘗試使用'-name'* .php'',並且grep對於遞歸和通配符不好,您需要使用-r – 2017-02-23 18:41:35
grep --include={*.php,*.html} -rnl './' -e "old" | xargs [email protected] sed -i 's/old/new/g' @
如果你有文件的列表,你可以使用
replace "old_string" "new_string" -- file_name1 file_name2 file_name3
如果你把所有的文件,你可以使用
replace "old_string" "new_string" -- *
如果您有擴展名的文件的列表,你可以使用
replace "old_string" "new_string" -- *.extension
其實,」--file「應該是」 - 「,在至少在我的版本中 – simpleuser 2014-10-07 23:34:30
此實用程序分佈在MySQL包中。 – 2014-10-14 16:00:11
雖然我想感謝解決方案,它沒有引用常規的行是正則表達式。 – 2014-10-14 16:05:41
要替換多個文件中的一個字符串,你可以使用:
grep -rl matchstring somedir/ | xargs sed -i 's/string1/string2/g'
例如
grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'
流編輯器,與-i
開關,這需要作爲參數結尾的備份文件調用並修改多個文件「就地」。所以
sed -i.bak 's/foo/bar/g' *
取代foo
在此文件夾中的所有文件bar
,但不會下降到子文件夾。然而,這將爲您的目錄中的每個文件生成一個新的.bak
文件。 要遞歸執行此目錄及其所有子目錄中的所有文件,您需要助手(如find
)來遍歷目錄樹。
find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *
find
讓你上的哪些文件來修改進一步的限制,通過指定如find ./ -name '*.php' -or -name '*.html' -print0
進一步論證,如果必要的。
注:GNU sed
不需要文件結尾,sed -i 's/foo/bar/g' *
會的工作,爲好; FreeBSD sed
要求擴展名,但允許在一個空格之間,所以sed -i .bak s/foo/bar/g *
工作。
腳本multiedit命令
multiedit [-n PATTERN] OLDSTRING NEWSTRING
從卡斯帕的答案我做了一個bash腳本接受命令行參數和可選限制模式匹配的文件名。保存在你的$ PATH中並生成可執行文件,然後使用上面的命令。
這裏的腳本:
#!/bin/bash
_help="\n
Replace OLDSTRING with NEWSTRING recursively starting from current directory\n
multiedit [-n PATTERN] OLDSTRING NEWSTRING\n
[-n PATTERN] option limits to filenames matching PATTERN\n
Note: backslash escape special characters\n
Note: enclose STRINGS with spaces in double quotes\n
Example to limit the edit to python files:\n
multiedit -n \*.py \"OLD STRING\" NEWSTRING\n"
# ensure correct number of arguments, otherwise display help...
if [ $# -lt 2 ] || [ $# -gt 4 ]; then echo -e $_help ; exit ; fi
if [ $1 == "-n" ]; then # if -n option is given:
# replace OLDSTRING with NEWSTRING recursively in files matching PATTERN
find ./ -type f -name "$2" -exec sed -i "s/$3/$4/g" {} \;
else
# replace OLDSTRING with NEWSTRING recursively in all files
find ./ -type f -exec sed -i "s/$1/$2/" {} \;
fi
要替換文件中的路徑(避免轉義字符),你可以使用下面的命令:
sed -i '[email protected][email protected][email protected]'
@符號意味着所有的特殊字符應該在以下字符串中被忽略。
正是我在尋找所有其他答案。也就是說,如何處理特殊字符,例如當改變一個字符串是一個路徑時。謝謝。在其他答案中看起來像是一個大的疏忽。 – inspirednz 2018-02-28 05:54:52
「你也可以使用find和sed,但我發現這個小的perl線工作得很好。
perl -pi -w -e 's/search/replace/g;' *.php
- -e手段執行下面的代碼行。
- -i手段編輯就地
- -w寫警告
- -p環
「(從http://www.liamdelahunty.com/tips/linux_search_and_replace_multiple_files.php中提取)
我最好的結果來自用perl和grep(以確保文件具有搜索表達式)
perl -pi -w -e 's/search/replace/g;' $(grep -rl 'search')
現在已經列出了一些標準答案,這樣。通常,您可以使用查找遞歸列出文件,然後使用sed或perl執行操作。
對於大多數快速使用,您可能會發現命令rpl更容易記住。這裏是更換(FOO - >吧),遞歸上的所有文件:
rpl -R foo bar .
你可能需要安裝它(apt-get install rpl
或類似)。
然而,對於涉及正則表達式和回代艱難的工作,或文件重命名以及搜索和替換,最普遍和強大的工具,我所知道的是repren,一個小的Python腳本,我寫了同時支持一些棘手的重命名和重構任務。您可能更喜歡它的原因是:
- 支持重命名文件以及搜索和替換文件內容。
- 在承諾執行搜索和替換之前查看更改。
- 支持帶後置替換的正則表達式,整個單詞,不區分大小寫和保留大小寫(替換foo - > bar,Foo - > Bar,FOO - > BAR)模式。
- 可以使用多種替換方式,包括掉換(foo - > bar和bar - > foo)或一組非替換(foo - > bar,f - > x)。
使用它,pip install repren
。例如Check the README。
哇,repren非常好!剛剛使用它來更改類名稱,方法和變量中的單詞的一部分,同時重命名文件以匹配1000多個C++頭文件和源文件,並且它在第一次使用一個命令時完美運行。謝謝! – 2017-11-01 18:49:37
如果文件中包含反斜槓(路徑通常情況下),你可以嘗試這樣的事:
sed -i -- 's,<path1>,<path2>,g' *
例如:
sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available)
以下命令可以用來首先搜索的文件和替換文件
找到。 | xargs grep搜索字符串| sed's/search string/new string/g'
例如find。 | xargs grep abc | sed's/abc/xyz/g'
我在找到這個問題(和答案)之前編寫了自己的解決方案。 我搜索了「替換」「幾個」和「xml」的不同組合,因爲這是我的應用程序,但沒有找到這個特定的組合。
我的問題:我有包含複雜對象的測試用例數據的spring xml文件。 java源代碼的重構改變了很多類,並且不適用於xml數據文件。爲了保存測試用例數據,我需要更改所有xml文件中的所有類名,分佈在多個目錄中。所有這些都保存了原始xml文件的備份副本(儘管這不是必須的,因爲版本控制會將我保存在這裏)。
我正在尋找find
+ sed
的某種組合,因爲它在其他情況下適用於我,但不能同時進行多次替換。
後來我發現ask ubuntu response,它幫助我建立我的命令行:
find -name "*.xml" -exec sed -s --in-place=.bak -e 's/firstWord/newFirstWord/g;s/secondWord/newSecondWord/g;s/thirdWord/newThirdWord/g' {} \;
它完美地工作(當然,我的情況有六種不同的替代品)。但請注意,它會觸及當前目錄下的所有* .xml文件。因此,如果您對版本控制系統負責,則可能需要首先進行篩選,然後只傳遞給sed
那些實際上具有所需字符串的人;像:
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' {} \;
和windows,我只是發現有一種方法可以找到字符串 - 還沒有檢查如何替換它 - 在一個命令中: 'findstr/spin/c:「quéquieresbuscar」* .xml ' 它會很方便。 – manuelvigarcia 2016-06-08 11:07:41
爲了維護我個人的英語節點,我寫了一個程序腳本,幫助來替代多個對舊/新字符串,對所有文件的目錄下遞歸。
多對舊/新字符串在哈希映射中進行管理。
可以通過命令行或環境變量設置目錄,地圖在腳本中是硬編碼的,但如果需要,您可以修改要從文件加載的代碼。
由於一些新功能,它需要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 [email protected] sed -i "s/$key/${itemMap[$key]}/g" @
done
echo -e "\nDone."
exit
我給用於在python源固定一個共同認領錯誤的例子。
您可以嘗試grep/sed方法。這裏是一個與GNU工程sed和不會打破一個混帳回購協議:
$ 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一起使用。
「foo」的第一行出現將替換爲「bar」。你可以使用第二行來檢查。
grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c
爲什麼你鏈接到你的博客?它包含與您的答案完全相同的文本。 – DavidPostill 2017-05-01 21:07:31
我喜歡'grep -rl'foo'。 | xargs sed -i's/foo/bar/g'' – Prachi 2017-07-11 21:04:36
我發現從另一個崗位這一項(不記得是哪),雖然不是最優雅的,它的簡單,作爲一個新手的Linux用戶給我任何麻煩
for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done
,如果你有空格或其他特殊字符使用\
for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
在子目錄字符串使用**
for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
$替換 「要從」 「」 - `找到/路徑/到/文件夾型F`
(更換 - MySQL數據庫系統的字符串替換實用工具)
真的跛腳,但我無法得到任何關於sed命令的工作的權利上OSX,所以我做了這個愚蠢的事情,而不是:
:%s/foo/bar/g
:wn
^- 這三行復制到剪貼板中我的(是的,包括終止換行符),那麼:
vi *
並按住command-v直到它說沒有剩下的文件。
阿呆... ...哈克有效...
如果你的字符串中有斜槓(/),你可以改變分隔符「+」。
find . -type f -exec sed -i 's+http://example.com+https://example.com+g' {} +
該命令將在當前目錄中遞歸運行。
謝謝!幫助將'../ domain.com'的引用加載到'domain.com' – 2018-03-08 17:29:28
- 1. Linux命令用另一個字符串替換LARGE文件中的字符串
- 2. 如何使用sed命令替換linux中的字符串?
- 3. Linux命令行:包含數字和替換字符串
- 4. 替換字符串命令
- 5. 如何在Linux中的命令行中將文本替換爲文件?
- 6. 如何在xml文件中查找/替換多個字符串?
- 7. 如何在多個文件上執行字符串替換?
- 8. Sed命令替換字符串行
- 9. 如何替換文件名中的多個字符串
- 10. 從linux命令行替換大文件中的特定非可打印字符
- 11. CMD惰性評估(字符串替換)+多個命令在單行中用「&」
- 12. Linux命令:在文件中的內容查找的字符串
- 13. 如何在Python中替換多個字符串中的一個子字符串?
- 14. 如何在Perl中替換字符串中的一個或多個字符串
- 15. 如何替換文件夾中多個文件中的字符串?
- 16. 如何用文件中的字符串替換字符串中的字符串
- 17. 替換文件linux命令中的未知行
- 18. 替換終端中所有文件中的多行字符串
- 19. Linux在文件名中查找並替換日文字符串
- 20. 多個命令行參數 - 替換字
- 21. 在linux中用\替換字符串
- 22. 在Linux下替換文件中的自定義字符串
- 23. Linux「rpl」命令不替換文字
- 24. 在PHP中替換多個字符串
- 25. 的Linux的bash:如何從bash命令行替換在文件2個詞語
- 26. 在linux命令行中用最大的文件替換字符串的最快方法?
- 27. 通過命令行在多個文件中搜索多個字符串
- 28. Bash:任何命令來替換文本文件中的字符串?
- 29. 替換zsh命令行中的字符串
- 30. 如何使用命令行(CLI)在word文檔上執行字符串替換
如果字符串中有空格或特殊字符,這似乎不適用於我。任何想法,爲什麼這可能,或者我需要逃避他們如何?謝謝! – 2014-08-06 17:54:20
至少對於我的'sed'版本,'-i'需要一個後面的字符串,它被附加到舊的文件名中。因此,'sed -i .bak's/foo/bar/g'* .xx'將所有'.xx'文件移動到等效的'.xx.bak'名稱,然後用foo生成'.xx'文件→條代替。 – Anaphory 2014-10-04 22:35:22
如果有人想要尋找更多的選擇,有一個關於unix堆棧交換的答案,它涵蓋了更多的用例站點http://unix.stackexchange.com/a/112024/13488 – Reddy 2015-05-22 09:40:02