Cách thay thế một chuỗi trong nhiều tệp trong dòng lệnh linux


461

Tôi cần thay thế một chuỗi trong rất nhiều tệp trong một thư mục, chỉ có sshquyền truy cập vào máy chủ. Tôi có thể làm cái này như thế nào?

Câu trả lời:


602
cd /path/to/your/folder
sed -i 's/foo/bar/g' *

Sự xuất hiện của "foo" sẽ được thay thế bằng "thanh".

Trên các hệ thống BSD như macOS, bạn cần cung cấp tiện ích mở rộng sao lưu như -i '.bak'"rủi ro tham nhũng hoặc nội dung một phần" trên mỗi trang.

cd /path/to/your/folder
sed -i '.bak' 's/foo/bar/g' *

13
Điều này dường như không hoạt động đối với tôi nếu chuỗi có khoảng trắng hoặc ký tự đặc biệt trong đó. Bất cứ ý tưởng tại sao điều đó có thể, hoặc tôi cần phải thoát khỏi chúng một số làm thế nào? Cảm ơn!
Matthew Herbst

13
Ít nhất là đối với phiên bản của tôi sed, -iyêu cầu một chuỗi sau nó, được gắn vào tên tệp cũ. Vì vậy, sed -i .bak 's/foo/bar/g' *.xxdi chuyển tất cả .xxcác tệp sang .xx.baktên tương đương và sau đó tạo các .xxtệp với sự thay thế thanh foo →.
Anaphory

24
Nếu bất cứ ai muốn tìm kiếm thêm tùy chọn, có một câu trả lời về trao đổi ngăn xếp unix bao gồm nhiều trường hợp sử dụng hơn trang web unix.stackexchange.com/a/112024/13488
Reddy

19
@MatthewHerbst để thoát khoảng trắng, sử dụng \ like sed -i 's/foo\ with\ spaces/bar/g' *. Tôi cho rằng bạn đã phát hiện ra sau một thời gian dài ... nhưng cách này vẫn giúp người khác tìm ra vấn đề tương tự.
manuelvigarcia

5
Đối với một cái gì đó đệ quy bạn có thể thử như sau. Lưu ý rằng nó không hoạt động nếu danh sách các tệp rất lớn. sed -i -e 's/foo/bar/g' $(find /home/user/base/dir)
Scot

243

Tương tự như câu trả lời của Kaspar nhưng với cờ g để thay thế tất cả các lần xuất hiện trên một dòng.

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

Đối với trường hợp toàn cầu không nhạy cảm:

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

23
Nếu bạn đang dùng OSX và các mẫu của bạn có thể chứa các dấu chấm và bạn muốn thay thế tại chỗ (không có tệp sao lưu), bạn nên sử dụng LC_ALL=C find ./ -type f -exec sed -i '' -e 's/proc.priv/priv/g' {} \;(xem bài đăng nàybài này )
Jonathan H

2
Điều này chắc chắn có hiệu quả với tôi, vì nó cho phép lọc với -name "* .js" '
Marcello de Sales

1
Một tùy chọn dài dòng sẽ rất tuyệt, nhưng bạn chỉ cần grep lại để xem các thay đổi đã được thực hiện chưa. Lưu ý: Đối với ký tự đại diện, hãy thử '-name "* .php"' và grep không tốt với đệ quy và ký tự đại diện, bạn cần thêm --include=*.whateverbằng -r
PJ Brunet

12
Đừng làm điều này từ gốc của một repo Git đã kiểm tra. Bạn có thể vô tình làm hỏng cơ sở dữ liệu của nó .git/. Hãy chắc chắn để cdxuống mức thấp hơn.
erikprice

1
Tôi chỉ làm điều này trong repo git của tôi và bây giờ git statustrở lại : error: bad index file sha1 signature.... fatal: index file corrupt. Đưa cái gì?
Jin

165

Câu trả lời của @ kev là tốt, nhưng chỉ ảnh hưởng đến các tệp trong thư mục ngay lập tức. Ví dụ bên dưới sử dụng grep để tìm đệ quy các tệp. Nó làm việc cho tôi mọi lúc.

grep -rli 'old-word' * | xargs -i@ sed -i 's/old-word/new-word/g' @

Sự cố lệnh

grep -r : --recursive , đọc đệ quy tất cả các tệp trong mỗi thư mục.
grep -l : --print-with-match , in tên của từng tệp có khớp, thay vì in các dòng khớp.
grep -i : - trường hợp khác .

xargs : biến đổi STDIN thành đối số, làm theo câu trả lời này .
Lệnh xargs -i @ ~ chứa @ ~ : một trình giữ chỗ cho đối số được sử dụng ở một vị trí cụ thể trong lệnh ~ ~ , dấu @ là một trình giữ chỗ có thể được thay thế bằng bất kỳ chuỗi nào.

sed -i : chỉnh sửa tập tin tại chỗ, không cần sao lưu.
sed s / regapi / thay thế / : chuỗi thay thế phù hợp với regrec với thay thế .
sed s / regapi / thay thế / g : toàn cầu , thực hiện thay thế cho mỗi trận đấu thay vì chỉ trận đấu đầu tiên.


13
điều này không hiệu quả với tôi, nhưng điều này đã làm:grep --include={*.php,*.html,*.js} -rnl './' -e "old-word" | xargs -i@ sed -i 's/old-word/new-word/g' @
Dennis

7
@pymarco Bạn có thể giải thích lệnh này không? Tôi không biết tại sao bạn phải sử dụng xargs thay vì chỉ sử dụng sed sau đó |, tại sao -itrong lệnh xargs? Tôi đọc trong hướng dẫn sử dụng nó không được dùng nữa và nên sử dụng -Ithay thế. Và được @sử dụng như một dấu phân cách cho bắt đầu và kết thúc cho mẫu?
Edson Horacio Junior

2
câu hỏi dành riêng cho linux
pymarco

6
Trên osx điều này là ok:grep -rli 'old-word' * | xargs -I@ sed -i '' 's/2.0.0/latest/g' @
Philippe Sultan

1
Sẽ thật tuyệt nếu bạn chia nhỏ một số tùy chọn ( rli) và @ví dụ về dấu hiệu
Roymunson

37

Điều này làm việc cho tôi:

find ./ -type f -exec sed -i 's/string1/string2/' {} \;

Howerver, điều này đã không : sed -i 's/string1/string2/g' *. Có lẽ "foo" không có nghĩa là chuỗi1 và "thanh" không phải là chuỗi2.


1
Đó là bởi vì sed đối xử với ký tự đại diện * khác nhau. [abc] * có nghĩa là số lượng ký tự tùy ý của tập {a, b, c}. [a-z0-9] * hoạt động tương tự như ký tự đại diện *.
thepiercingarrow

8
Trên OSX sử dụng:find ./ -type f -exec sed -i '' -e 's/string1/string2/' {} \;
Shaheen Ghiassy

32

Có một vài câu trả lời tiêu chuẩn cho điều này đã được liệt kê. Nói chung, bạn có thể sử dụng find để liệt kê đệ quy các tệp và sau đó thực hiện các thao tác với sed hoặc perl .

Đối với hầu hết các sử dụng nhanh chóng, bạn có thể thấy lệnh rpl dễ nhớ hơn nhiều. Đây là sự thay thế (foo -> bar), đệ quy trên tất cả các tệp:

rpl -R foo bar .

Có lẽ bạn sẽ cần phải cài đặt nó (apt-get install rpl hoặc tương tự).

Tuy nhiên, đối với các công việc khó khăn hơn liên quan đến biểu thức chính quy và thay thế trở lại, hoặc đổi tên tệp cũng như tìm kiếm và thay thế, công cụ mạnh mẽ và tổng quát nhất mà tôi biết là repren , một đoạn mã Python nhỏ mà tôi đã viết trước đây cho một số đổi tên và tái cấu trúc nhiệm vụ. Những lý do bạn có thể thích nó là:

  • Hỗ trợ đổi tên tập tin cũng như tìm kiếm và thay thế nội dung tập tin.
  • Xem các thay đổi trước khi bạn cam kết thực hiện tìm kiếm và thay thế.
  • Hỗ trợ các biểu thức chính quy với các chế độ thay thế trở lại, toàn bộ từ, không phân biệt chữ hoa chữ thường và bảo quản trường hợp (thay thế các chế độ foo -> bar, Foo -> Bar, FOO -> BAR).
  • Hoạt động với nhiều thay thế, bao gồm hoán đổi (foo -> thanh và thanh -> foo) hoặc bộ thay thế không duy nhất (foo -> bar, f -> x).

Để sử dụng nó , pip install repren. Kiểm tra README cho ví dụ.


1
Wow, repren là tuyệt vời! Chỉ cần sử dụng nó để thay đổi một phần của một từ bên trong tên lớp, phương thức và biến trong khi đổi tên tệp để khớp với hơn 1000 tệp tiêu đề và tệp C ++ và lần đầu tiên nó hoạt động hoàn hảo với một lệnh. Cảm ơn bạn!
Bob Kocisko

29

Để thay thế một chuỗi trong nhiều tệp, bạn có thể sử dụng:

grep -rl string1 somedir/ | xargs sed -i 's/string1/string2/g'

Ví dụ

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

Nguồn blog


20

Để thay thế một đường dẫn trong tệp (tránh các ký tự thoát), bạn có thể sử dụng lệnh sau:

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

Dấu @ có nghĩa là tất cả các ký tự đặc biệt sẽ bị bỏ qua trong một chuỗi sau.


2
Chính xác những gì tôi đang tìm kiếm trong tất cả các câu trả lời khác. Cụ thể, làm thế nào để đối phó với các ký tự đặc biệt, chẳng hạn như khi thay đổi một chuỗi là một đường dẫn. Cảm ơn bạn. Có vẻ như một sự giám sát lớn trong các câu trả lời khác.
lấy cảm hứng từ

19

Trong trường hợp chuỗi của bạn có dấu gạch chéo (/) trong đó, bạn có thể thay đổi dấu phân cách thành '+'.

find . -type f -exec sed -i 's+http://example.com+https://example.com+g' {} +

Lệnh này sẽ chạy đệ quy trong thư mục hiện tại.


Cảm ơn! Giúp thay đổi một tải tài liệu tham khảo của ../domain.comđểdomain.com
Jack Rogers

12

Sự xuất hiện dòng đầu tiên của "foo" sẽ được thay thế bằng "thanh". Và bạn có thể sử dụng dòng thứ hai để kiểm tra.

grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c

6
Tại sao bạn liên kết đến blog của bạn? Nó chứa chính xác cùng một văn bản như câu trả lời của bạn.
DavidPostill

1
tôi thíchgrep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
Prachi

10

Nếu bạn có danh sách các tập tin bạn có thể sử dụng

replace "old_string" "new_string" -- file_name1 file_name2 file_name3

Nếu bạn có tất cả các tập tin bạn có thể sử dụng

replace "old_string" "new_string" -- *

Nếu bạn có danh sách các tệp có phần mở rộng, bạn có thể sử dụng

replace "old_string" "new_string" -- *.extension

2
thực ra, "--file" chỉ nên là "-", ít nhất là trong phiên bản của tôi
đơn giản hóa

4
Tiện ích này được phân phối trong các gói MySQL.
Dmitry Ginzburg

2
Mặc dù tôi muốn đánh giá cao giải pháp, hoạt động mà không trích dẫn dòng thông thường là biểu thức chính quy.
Dmitry Ginzburg

1
Điều này hoạt động tốt - và nếu bạn muốn thay thế tất cả các chuỗi trong nhiều tệp, kết thúc bằng ".txt", bạn chỉ có thể làmreplace "old_string" "new_string" -- *.txt
tsveti_iko

1
Tốt hơn là thêm từ đâu để có được replacetiện ích này . Không có thông tin này, câu trả lời này là không đầy đủ.
Sitesh

8

"Bạn cũng có thể sử dụng find và sed, nhưng tôi thấy rằng dòng perl nhỏ này hoạt động độc đáo.

perl -pi -w -e 's/search/replace/g;' *.php
  • -e có nghĩa là thực thi dòng mã sau.
  • -i có nghĩa là chỉnh sửa tại chỗ
  • -w viết cảnh báo
  • vòng lặp -p

"(Trích xuất từ http: // www. Nghịdelahunty.com / tip / linux_search_and_Vplace_mult Môn_files.php )

Kết quả tốt nhất của tôi đến từ việc sử dụng perl và grep (để đảm bảo rằng tệp có biểu thức tìm kiếm)

perl -pi -w -e 's/search/replace/g;' $( grep -rl 'search' )

8

Cho rằng bạn muốn tìm kiếm chuỗi searchvà thay thế nó bằng replacenhiều tệp, đây là công thức một dòng được thử nghiệm trong trận chiến của tôi :

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

Giải thích nhanh về grep:

  • -R - tìm kiếm đệ quy
  • -i - trường hợp không nhạy cảm
  • -I - bỏ qua các tệp nhị phân (bạn muốn văn bản, phải không?)
  • -l- in một danh sách đơn giản như đầu ra. Cần thiết cho các lệnh khác

Đầu ra grep sau đó được chuyển sang sed (thông qua xargs) được sử dụng để thực sự thay thế văn bản. Các -ilá cờ sẽ làm thay đổi các tập tin trực tiếp. Hủy bỏ nó cho một loại chế độ "chạy khô".


4

Tôi đã tự pha chế giải pháp của riêng mình trước khi tôi tìm thấy câu hỏi này (và câu trả lời). Tôi đã tìm kiếm các kết hợp khác nhau của "thay thế" "vài" và "xml", vì đó là ứng dụng của tôi, nhưng không tìm thấy kết hợp cụ thể này.

Vấn đề của tôi: Tôi đã có các tệp xml mùa xuân với dữ liệu cho các trường hợp thử nghiệm, có chứa các đối tượng phức tạp. Một bộ cấu trúc lại mã nguồn java đã thay đổi rất nhiều lớp và không áp dụng cho các tệp dữ liệu xml. Để lưu dữ liệu trường hợp thử nghiệm, tôi cần thay đổi tất cả các tên lớp trong tất cả các tệp xml, được phân phối trên một số thư mục. Tất cả trong khi lưu các bản sao lưu của các tệp xml gốc (mặc dù điều này không bắt buộc, vì kiểm soát phiên bản sẽ lưu tôi ở đây).

Tôi đã tìm kiếm một số kết hợp find+ sed, bởi vì nó hoạt động cho tôi trong các tình huống khác, nhưng không phải với một vài sự thay thế cùng một lúc.

Sau đó, tôi tìm thấy câu hỏi ubfox và nó đã giúp tôi xây dựng dòng lệnh của mình:

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

Và nó hoạt động hoàn hảo (tốt, trường hợp của tôi có sáu lần thay thế khác nhau). Nhưng xin lưu ý rằng nó sẽ chạm vào tất cả các tệp * .xml trong thư mục hiện tại. Do đó, và nếu bạn chịu trách nhiệm với hệ thống kiểm soát phiên bản, bạn có thể muốn lọc trước và chỉ truyền cho sednhững người thực sự có chuỗi bạn muốn; giống:

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' {} \;

và đối với các cửa sổ, tôi chỉ phát hiện ra rằng có một cách để tìm chuỗi - không kiểm tra xem làm thế nào để thay thế nó-- trong một lệnh: findstr /spin /c:"quéquieresbuscar" *.xml Nó sẽ rất hữu ích.
manuelvigarcia

3
grep --include={*.php,*.html} -rnl './' -e "old" | xargs -i@ sed -i 's/old/new/g' @

3

Thực sự khập khiễng, nhưng tôi không thể có bất kỳ lệnh sed nào hoạt động ngay trên OSX, vì vậy tôi đã làm điều ngu ngốc này thay vào đó:

:%s/foo/bar/g
:wn

^ - sao chép ba dòng này vào bảng tạm của tôi (có, bao gồm dòng mới kết thúc), sau đó:

vi *

và giữ lệnh-v cho đến khi nó nói không còn tệp nào.

Câm ... hacky ... hiệu quả ...


3

Trên MacBook Pro, tôi đã sử dụng như sau (lấy cảm hứng từ https://stackoverflow.com/a/19457213/6169225 ):

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

-i '' sẽ đảm bảo bạn không lấy bản sao lưu.

-e cho regex hiện đại.


3
-echỉ nói với sed rằng mã thông báo tiếp theo là một lệnh. Đối với các biểu thức chính quy mở rộng, sử dụng -Ethay thế.
Benjamin W.

2

Trình chỉnh sửa luồng thực hiện sửa đổi nhiều tập tin -i, trong đó có một tập tin trực tuyến, khi được gọi bằng khóa chuyển, sẽ lấy một tập tin sao lưu kết thúc làm đối số. Vì thế

sed -i.bak 's/foo/bar/g' *

thay thế foobằng bartrong tất cả các tệp trong thư mục này, nhưng không hạ xuống thành các thư mục con. Tuy nhiên, điều này sẽ tạo ra một .baktệp mới cho mọi tệp trong thư mục của bạn. Để thực hiện điều này một cách đệ quy cho tất cả các tệp trong thư mục này và tất cả các thư mục con của nó, bạn cần một người trợ giúp, như find, để duyệt qua cây thư mục.

find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *

findcho phép bạn hạn chế thêm về những tệp cần sửa đổi, bằng cách chỉ định thêm các đối số như find ./ -name '*.php' -or -name '*.html' -print0, nếu cần.


Lưu ý: GNU sedkhông yêu cầu một tệp kết thúc, sed -i 's/foo/bar/g' *cũng sẽ hoạt động; FreeBSD sedyêu cầu một phần mở rộng, nhưng cho phép một không gian ở giữa, vì vậy sed -i .bak s/foo/bar/g *hoạt động.


2

tập lệnh cho lệnh multiedit

multiedit [-n PATTERN] OLDSTRING NEWSTRING

Từ câu trả lời của Kaspar, tôi đã tạo một tập lệnh bash để chấp nhận các đối số dòng lệnh và tùy ý giới hạn tên tệp khớp với một mẫu. Tiết kiệm trong $ PATH của bạn và thực hiện, sau đó chỉ cần sử dụng lệnh ở trên.

Đây là kịch bản:

#!/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

1

Nếu tệp chứa dấu gạch chéo ngược (đường dẫn thường), bạn có thể thử một cái gì đó như thế này:

sed -i -- 's,<path1>,<path2>,g' *

Ví dụ:

sed -i -- 's,/foo/bar,/new/foo/bar,g' *.sh (in all shell scripts available)

1

Để duy trì nút tiếng Anh cá nhân của mình, tôi đã viết một tập lệnh tiện ích giúp thay thế nhiều cặp chuỗi cũ / mới, cho tất cả các tệp trong một thư mục theo cách đệ quy.

Nhiều cặp chuỗi cũ / mới được quản lý trong bản đồ băm.

Có thể đặt dir thông qua dòng lệnh hoặc biến môi trường, bản đồ được mã hóa cứng trong tập lệnh, nhưng bạn có thể sửa đổi mã để tải từ tệp, nếu cần.

Nó yêu cầu bash 4.2, do một số tính năng mới.

en_st Chuẩn hóa.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

1

Sử dụng lệnh ack sẽ nhanh hơn rất nhiều như thế này:

ack '25 Essex' -l | xargs sed -i 's/The\ fox \jump/abc 321/g'

Ngoài ra nếu bạn có một khoảng trắng trong kết quả tìm kiếm. Bạn cần phải thoát khỏi nó.


0

Tôi đang đưa ra một ví dụ để sửa một lỗi shebang phổ biến trong các nguồn python.

Bạn có thể thử phương pháp grep / sed. Đây là một cái hoạt động với GNU sed và sẽ không phá vỡ một repo git:

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

Hoặc bạn có thể sử dụng greptile :)

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

Tôi vừa thử nghiệm kịch bản đầu tiên, và kịch bản thứ hai cũng hoạt động tốt. Hãy cẩn thận với các ký tự thoát, tôi nghĩ rằng nó sẽ dễ sử dụng greptile hơn trong hầu hết các trường hợp. Tất nhiên, bạn có thể làm nhiều điều thú vị với sed, và vì thế có thể tốt hơn là thành thạo sử dụng nó với xargs.


0

Tôi đã tìm thấy bài này từ một bài đăng khác (không thể nhớ bài nào) và mặc dù không phải là trang nhã nhất, nó đơn giản và như một người dùng Linux mới làm cho tôi không gặp rắc rối

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

nếu bạn có khoảng trắng hoặc các ký tự đặc biệt khác, hãy sử dụng \

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

đối với các chuỗi trong thư mục con sử dụng **

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

0

Lệnh dưới đây có thể được sử dụng để tìm kiếm tệp trước và thay thế tệp:

find . | xargs grep 'search string' | sed 's/search string/new string/g'

Ví dụ

find . | xargs grep abc | sed 's/abc/xyz/g'

0

Có một cách dễ dàng hơn bằng cách sử dụng tệp tập lệnh đơn giản:

   # sudo chmod +x /bin/replace_string_files_present_dir

mở tập tin trong gedit hoặc một trình soạn thảo bạn chọn, tôi sử dụng gedit ở đây.

   # sudo gedit /bin/replace_string_files_present_dir

Sau đó, trong trình chỉnh sửa dán sau đây trong tập tin

   #!/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.

Lưu tệp, đóng gedit , sau đó thoát khỏi thiết bị đầu cuối của bạn hoặc chỉ cần đóng nó và sau đó khởi động nó để có thể tải tập lệnh mới mà bạn đã thêm.

Điều hướng đến thư mục mà bạn có nhiều tệp bạn muốn chỉnh sửa. Sau đó chạy:

  #replace_string_files_present_dir

Nhấn enter và điều này sẽ tự động thay thế chuỗi chuỗi cũ1 trong tất cả các tệp chứa chúng với chuỗi mớichuỗi mới1 tương ứng.

Nó sẽ bỏ qua tất cả các thư mục và tệp không chứa các chuỗi cũ.

Điều này có thể giúp loại bỏ công việc gõ tẻ nhạt trong trường hợp bạn có nhiều thư mục với các tệp cần thay thế chuỗi. Tất cả bạn phải làm là điều hướng đến từng thư mục đó, sau đó chạy:

#replace_string_files_present_dir

Tất cả bạn phải làm là đảm bảo bạn đã bao gồm hoặc thêm tất cả các chuỗi thay thế như tôi đã trình bày ở trên:

replace "oldstring" "newstring" -- *

ở cuối tập tin / bin / thay_opes_files_present_dir .

Để thêm một chuỗi thay thế mới, chỉ cần mở tập lệnh mà chúng ta đã tạo bằng cách nhập đoạn mã sau vào terminal:

sudo gedit /bin/replace_string_files_present_dir

Đừng lo lắng về số lượng chuỗi thay thế bạn thêm vào, chúng sẽ không có hiệu lực nếu không tìm thấy chuỗi cũ .


Thông thường, khi mọi người hỏi "làm thế nào để $ {bất cứ điều gì}" trong bash, họ đang yêu cầu một phiên bản nhỏ gọn để đưa vào một tập lệnh hoặc hướng dẫn công việc CI (nói a .gitlab-ci.ymlhoặc a travis.yml). Mỗi lượt bao gồm việc viết một tập lệnh để thực thi nó sau này là một kiểu chống mẫu, vì sau đó bạn sẽ cần phải tạo kịch bản cho việc tạo tập lệnh (và tôi thường lộn xộn, hầu hết thời gian)
zar3bski

-4

$ thay thế "Từ" "Tới" - `find / path / to / library -type f`

(thay thế - một tiện ích thay thế chuỗi của Hệ thống cơ sở dữ liệu MySQL)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.