How to locate files that contain a specific word in a specific folder first, then replace it with a different one in Mac Terminal - macos

i'm looking for a solution within Mac Terminal to first locate a specific word e.g. "testword" in a folder with a lot of text files in it and then replace the word with a different one.
I found the following line to locate a word in a folder with several text files in it:
grep -r 'testword' "path"
which works fine but i can't find a line to add to replace the word with another one in one combined command. Any suggestions?
Thanks a lot for your help! :)

For safety, I would suggest to do it in two steps. Using first grep, tr and sed to prepare all word replacements for each files. Check if all is okay, then execute all the sed remplacements.
$ touch hello123 helloABC helloXYZ hello000
$ echo "hello" > hello*
$ cat hello*
hello
hello
hello
hello
$ grep -lr "hello" . | tr "\n" " " | sed 's/^/sed \-i "s\/hello\/NewWord\/g" /g' | tee replace.sh
sed -i "s/hello/NewWord/g" ./helloXYZ ./helloABC ./hello000 ./hello123
$ sh replace.sh
$ cat hello*
NewWord
NewWord
NewWord
NewWord

Related

How to append string at the end of text file without leading line break?

$ cat test.txt
foo
$ echo " bar" | tee -a test.txt
foo
bar
Expected result for cat test.txt is foo bar.
You can use sed:
sed -i~ '$ s/$/ bar/' test.txt
$ is an address that means "the last line". It applies to the following command.
s/$/ bar/ replaces $, i.e. the end of line, by bar.
-i (if supported) will change the file in place, leaving the original as a backup (renamed to test.txt~). If your sed doesn't support it, redirect the output to a new file and move it over the old one.
I prefer to use ed over sed -i to edit files in place, as, unlike sed -i, it's standardized and works the same everywhere:
printf "%s\n" '$s/$/ bar/' w | ed -s test.txt
The commands are very similar; sed descended from ed as a way to work on text in the middle of a pipeline. The big change is w to write the changed file back to disk.

How to replace a particular string with another in UNIX shell script

Could you please let me know how to replace a particular string present in a text file or ksh file in the server with another string ?
For example :-
I have 10 files present in the path /file_sys/file in which i have to replace the word "BILL" to "BILLING" in all the 10 files.
Works for me:
I created a file 'test' with this content: "This is a simple test". Now I execute this call to the sed command:
sed -i 's/ is / is not /' test
Afterwards the file 'test' contains this content: "This is not a simple test"
If your sed utility does not support the -i flag, then there is a somewhat awkward workaround:
sed 's/ is / is not /' test > tmp_test && mv tmp_test test
This should work. Please find the testing as well.
$ cat > file1
I am a BILL boy
sed 's/[[:alnum:] [:cntrl:] [:lower:] [:space:] [:alpha:] [:digit:] [:print:] [:upper:] [:blank:] [:graph:] [:punct:] [:xdigit:]]BILL[[:alnum:] [:cntrl:] [:lower:] [:space:] [:alpha:] [:digit:] [:print:] [:upper:] [:blank:] [:graph:] [:punct:] [:xdigit:]]/BILLING/g' file1>file2
$ cat file2
I am a BILLING boy
Using sed:
sed 's/\bBILL\b/BILLING/g' file
For inplace:
sed --in-place 's/\bBILL\b/BILLING/g' file
A little for loop might assist for dealing with multiple files, and here I'm assuming -i option is not available:
for file in $(grep -wl BILL /file_sys/file/*); do
echo $file
sed -e 's/\bBILL\b/BILLING/g' $file > tmp
mv tmp $file
done
Here's what's happening:
grep -w Search for all (and only) files with the word BILL
grep -l Listing the file names (rather than content)
$(....) Execute whats inside the brackets (command substitution)
for file in Loop over each item in the list (each file with BILL in it)
echo $file Print each file name we loop over
sed command Replace the word BILL (here, specifically delimited with word boundaries "\b") with BILLING, into a tmp file
mv command Move the tmp file back to the original name (replace original)
You can easily test this without actually changing anything - e.g. just print the file name, or just print the contents (to make sure you've got what you expect before replacing the original files).

Quotation marks in text file

I am new to using Unix and R etc. I am in the process of analysing some data from the NCBI website using GEO 2r datasets. I have downloaded some data from the website and have it in a text file. However, the data has quotation marks throughout and I am trying to get rid of these but have been unable to do so. The file is called GSE23182_geo2r.txt and have used following functions:
sed 's/\"//g' GSE23182_geo2r.txt > GSE23182_geo2r_2.txt
and
sed 's/\"//g' GSE23182_geo2r.txt
and
sed "s/\"//g" GSE23182_geo2r.txt
and
cat GSE23182_geo2r.txt | tr -d '\"' > GSE23182_geo2r_2.txt
but none of them have worked and seem to present with the problem: no such file or directory
Would be so grateful for any help!!
Thanks
File 'test' contains lots of "
The contents of the file are:
$ cat test
hi " this is a a quote"
"'"starting quote""
Now to delete " we use tr -d command.
$ cat test |tr -d "\""
hi this is a a quote
'starting quote
Now you can re-direct this to another file as under:
$ cat test |tr -d "\"" >test1
$ cat test1
hi this is a a quote
'starting quote
One simple way would be to open the file in vim and issue the command:
:%s/\"//g
This would remove " throughout the file.

sed command creates randomly named files

I recently wrote a script that does a sed command, to replace all the occurrences of "string1" with "string2" in a file named "test.txt".
It looks like this:
sed -i 's/string1/string2/g' test.txt
The catch is, "string1" does not necessarily exist in test.txt.
I notice after executing a bunch of these sed commands, I get a number of empty files, left behind in the directory, with names that look like this:
"sed4l4DpD"
Does anyone know why this might be, and how I can correct it?
-i is the suffix given to the new/output file. Also, you need -e for the command.
Here's how you use it:
sed -i '2' -e 's/string1/string2/g' test.txt
This will create a file called test.txt2 that is the backup of test.txt
To replace the file (instead of creating a new copy - called an "in-place" substitution), change the -i value to '' (ie blank):
sed -i '' -e 's/string1/string2/g' test.txt
EDIT II
Here's actual command line output from a Mac (Snow Leopard) that show that my modified answer (removed space from between the -i and the suffix) is correct.
NOTE: On a linux server, there must be no space between it -i and the suffix.
> echo "this is a test" > test.txt
> cat test.txt
this is a test
> sed -i '2' -e 's/a/a good/' test.txt
> ls test*
test.txt test.txt2
> cat test.txt
this is a good test
> cat test.txt2
this is a test
> sed -i '' -e 's/a/a really/' test.txt
> ls test*
test.txt test.txt2
> cat test.txt
this is a really good test
I wasn't able to reproduce this with a quick test (using GNU sed 4.2.1) -- but strace did show sed creating a file called sedJd9Cuy and then renaming it to tmp (the file named on the command line).
It looks like something is going wrong after sed creates the temporary file and before it's able to rename it.
My best guess is that you've run out of room in the filesystem; you're able to create a new empty file, but unable to write to it.
What does df . say?
EDIT:
I still don't know what's causing the problem, but it shouldn't be too difficult to work around it.
Rather than
sed -i 's/string1/string2/g' test.txt
try something like this:
sed 's/string1/string2/g' test.txt > test.txt.$$ && mv -f test.txt.$$ test.txt
Something is going wrong with the way sed creates and then renames a text file to replace your original file. The above command uses sed as a simple input-output filter and creates and renames the temporary file separately.
So after much testing last night, it turns out that sed was creating these files when trying to operate on an empty string. The way i was getting the array of "$string1" arguments was through a grep command, which seems to be malformed. What I wanted from the grep was all lines containing something of the type "Text here '.'".
For example the string, "Text here 'ABC.DEF'" in a file, should have been caught by grep, then the ABC.DEF portion of the string, would be substituted by ABC_DEF. Unfortunately the grep I was using would catch lines of the type "Text here ''" (that is, nothing between the ''). When later on, the script attempted to perform a sed replacement using this empty string, the random file was created (probably because sed died).
Thanks for all your help in understanding how sed works.
Its better if you do it in this way:
cat large_file | sed 's/string1/string2/g' > file_filtred

Delete line ending with a newline character in text file

I need to delete the same line in a large number of text files. I have been trying to use sed, but I cannot get it to delete the newline character at the end. The following successfully deletes the line, but not the newline:
sed -i -e 's/VERSION:1//' *.txt
I have tried using the following to delete the newline also, but it does not work:
sed -i -e 's/VERSION:1\n//' *.txt
Is there anyway to specify a newline in a sed substitute command OR is there any other command line tool I can use to achieve my goal? Thank you
You can use the sed command:
sed -i -e '/VERSION:1/d'
for this.
The following transcript gives an example:
pax> echo 'hello
> goodbye
> hello again' | sed '/oo/d'
hello
hello again
You should also check whether you want to match whole lines with, for example:
sed -i -e '/^VERSION:1$/d'
since, as it stands, that will also delete lines like the following:
VERSION:10
CONVERSION:1
sed '/VERSION:1/{:q;N;s/VERSION\n//g;t q}' file

Resources