How to replace text strings by reading in list using sed

1

1

I'm trying to come up with a sed script to run from the shell. I need to be able to read in a list of UUIDs from an external file, which contains two columns

origtexta replacementa
origtextb replacementb
origtextc replacementc

The script needs to act recursively on all txt files below the current folder, look for any instance of 'origtext?' and replace with the corresponding text from column 2. It would be great if the script could be stored in /home/myuser/Scripts/ and aliased to be able to be run from anywhere I invoke it, and would also be nice if the script saved the original txt file as .txt.orig before changing it.

I've been testing this bit so far:

#!/bin/sed
while read n k; do sed -i 's/$n/$k/g' *.txt; done < list

which I found in this thread: How to replace a list of strings by another list

It seems to be doing something, because the dates of the files change to the current date/time, but no text is actually replaced so I'm not at all sure how to get this working.

graphics.guy

Posted 2014-03-01T16:53:59.907

Reputation: 13

Answers

2

I would stick to bash for this. build the sed script dynamically

while read uuid uuid_alias; do 
    sed_script+="s/$uuid/$uuid_alias/g;"
done < list

find . -type f -name \*.txt -exec sed -i "$sed_script" '{}' +

You need to try to invoke sed as few times as possible for time efficiency.

Also note that $variables are not expanded inside 'single quotes' -- "double quotes" allow variable expansion.

glenn jackman

Posted 2014-03-01T16:53:59.907

Reputation: 18 546

Bear with me as I'm very new to this. When I drop that into a file named uuidrepl.sh and attempt to run it, I get:

bash: ./uuidrepl.sh: /bin/bash^M bad interpreter: No such file or directory – graphics.guy – 2014-03-01T19:06:29.260

Your text editor is using DOS-style line endings (carriage return plus newline). Your OS only recognizes newlines, and treats carriage returns like plain old characters, so the OS is looking for an interpreter names "/bin/bash<CR>" and there's no such file. If you edit your scripts on Windows, use a text editor that can save files with "Unix-style" line endings. Alternately, when you transfer your scripts to linux, use the dos2unix program to strip out the carriage returns. – glenn jackman – 2014-03-01T20:38:17.317

Hmm, I'm not sure that's the case. I just retyped the script manually in nano and it gives me the same error. Just so we're on the same page, I now have a folder containing two text files with random text plus some sample strings to replace (test1.txt and test2.txt), a 'list' file containing the replacement pairs, and a uuidrepl.sh script which contains the header #!/bin/bash and the full contents of your code block from above. – graphics.guy – 2014-03-01T21:19:15.410

I took another look at it this morning and I think there may have been an extra linebreak that got pushed down in my first attempt. I was able to get the script to run on some test files, so you were right. Thanks for that! I'm now trying to figure out how to create a backup of the original as .txt.orig prior to running the replace sequence. – graphics.guy – 2014-03-02T16:10:23.350

Simplest way: sed -i.orig ... – glenn jackman – 2014-03-02T16:33:55.050

Just wanted to thank you for your help with this. I've been able to get it running and made some modifications along the way to customize it even more. Wasn't able to comment sooner. – graphics.guy – 2014-03-04T02:36:16.017