Solved

Find and replace for all files in directory

Posted on 2004-10-14
11
259 Views
Last Modified: 2013-12-06
Hello,

I want to find all instances of "ABC123" (case sensitive) in ALL files in the directory /home/usr/stuff/ file.txt and replace all the instances with "LMNOP789"

The ownership and permissions must be preserved.

How can this be done from a command line?
I am using Red Hat 7.

Thanks!
0
Comment
Question by:hankknight
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +4
11 Comments
 
LVL 6

Expert Comment

by:blkline
ID: 12310824
cd /home/usr/stuff; for f in $(ls *.txt); do cat $f | sed -e 's/ABC123/LMNOP789/g' > tmp$$.txt && chown --reference=$f tmp$$.txt; chmod --reference=$f tmp$$.txt; mv -f tmp$$.txt $f; done

Keep in mind that if the owner of the file is someone other than yourself and you're not running as root then you may not be able to overwrite the file.

Written to be more legible it looks like this:

cd /home/usr/stuff
for f in $(ls *.txt)
do
    cat $f | sed -e 's/ABC123/LMNOP789/g' > tmp$$.txt \
    && chown --reference=$f tmp$$.txt; \
    chmod --reference=$f tmp$$.txt; \
    mv -f tmp$$.txt $f
done
0
 
LVL 2

Expert Comment

by:Sunjith
ID: 12311009
>I want to find all instances of "ABC123" (case sensitive) in ALL files in the directory /home/usr/stuff/  and
>replace all the instances with "LMNOP789"
>
>The ownership and permissions must be preserved.

Here's the script (one method) for that:
--------
for i in `find /home/usr/stuff/ -type f`; do vi -e -c "%s/ABC123/LMNOP789/g" -c "wq" $i; done
--------
Copy the command exactly. If you are typing, make sure all quotations are correct (Note that the first two single quotes is the key usually above your 'tab' key).
0
 
LVL 6

Expert Comment

by:blkline
ID: 12311050
I never gave a thought to using vi in this manner.   Thanks!

Oh, make it:

find /home/usr/stuff/ -type f -name "*.txt"   as I think from the specs that the filenames all have a txt extension.
0
U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

 
LVL 2

Expert Comment

by:Sunjith
ID: 12311474
You are welcome. BTW, FYI, the filenames need not necessarily have a txt extension.
0
 
LVL 16

Author Comment

by:hankknight
ID: 12311637
Thanks!  It worked, but it returned several pages of errors:

                   Error detected while processing command line:
                   Pattern not found: storefront

For future refference, is there a way to supress the errors?

Thanks!
0
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 12313555
You get the errors because some of the "ALL files in the directory" don't
contain the source pattern for the replace.  Rather than 'find', why don't
you use 'grep -l' to limit the files to those that contain the source pattern.

for i in `grep -l "ABC123" /home/usr/stuff/*.txt`; do vi -e -c "%s/ABC123/LMNOP789/g" -c "wq" $i; done

0
 
LVL 10

Assisted Solution

by:Luxana
Luxana earned 100 total points
ID: 12314078
> For future refference, is there a way to supress the errors?

you can redirect standart error to /dev/null

lets take blkline's example :

find /home/usr/stuff/ -type f -name "*.txt" 2> /dev/null

so all errors will be send to /dev/null and you get just STDOUT
0
 
LVL 38

Assisted Solution

by:yuzh
yuzh earned 100 total points
ID: 12314656
How about:

(find /home/usr/stuff/ -type f | xarg vi -e -c "%s/ABC123/LMNOP789/g" -c "wq" ) 2>/dev/null

please credit to  Sunjith's vi statement, you can also use perl/sed to do the same job.
0
 
LVL 2

Accepted Solution

by:
Sunjith earned 300 total points
ID: 12315135
> (find /home/usr/stuff/ -type f | xarg vi -e -c "%s/ABC123/LMNOP789/g" -c "wq" ) 2>/dev/null

That's good. Just a correction. It should be "xargs" instead of "xarg"

Grepping is a better idea than find because it filters out the files needed to be processed by vi and grep processes file much faster than vi. Combining all the ideas, the better command would be:
--------
grep -srl "ABC123" /home/usr/stuff/ | xargs vi -e -c "%s/ABC123/LMNOP789/g" -c "wq"
--------

Though there wouldn't be too many errors as you got with the previous script, if you are very particular, you may redirect the std error as well:
--------
grep -srl "ABC123" /home/usr/stuff/ | xargs vi -e -c "%s/ABC123/LMNOP789/g" -c "wq" 2>/dev/null
--------
0
 
LVL 38

Expert Comment

by:yuzh
ID: 12315163
Sorry about the typo, it should be "xargs", Sunjith thanks for the correction.
0
 
LVL 4

Expert Comment

by:EinarTh
ID: 12317537
I'd use grep a bit differently:

for f in $(find /usr/home/stuff -type f) ; do grep ABC123 $f && cat $f | sed "s/ABC123/LMNOP789/g" > tmp$$.txt && chown --reference=$f tmp$$.txt; mv -f tmp$$.txt $f; done

0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Upgraded from Debian 7 to 8.7 and got black screen 20 120
The better OS Architecture 13 106
Let's Encrypt - Auto Renew Failure via Cron Job 1 61
IMAP copying tool 14 71
The purpose of this article is to fix the unknown display problem in Linux Mint operating system. After installing the OS if you see Display monitor is not recognized then we can install "MESA" utilities to fix this problem or we can install additio…
Google Drive is extremely cheap offsite storage, and it's even possible to get extra storage for free for two years.  You can use the free account 15GB, and if you have an Android device..when you install Google Drive for the first time it will give…
Learn how to find files with the shell using the find and locate commands. Use locate to find a needle in a haystack.: With locate, check if the file still exists.: Use find to get the actual location of the file.:
Learn how to navigate the file tree with the shell. Use pwd to print the current working directory: Use ls to list a directory's contents: Use cd to change to a new directory: Use wildcards instead of typing out long directory names: Use ../ to move…
Suggested Courses

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question