Can I search/replace in multiple .txt files quickly from Terminal? [duplicate] - macos

This question already has answers here:
Recursive search and replace in text files on Mac and Linux
(14 answers)
Closed 7 years ago.
I have about 100 .txt files that contain plain text. Somehow, some of the data has been corrupted and needs to be found/replaced.
I need to search for the characters'--' and replace it with a long dash: '—'.
Is there a way to do this quickly with a command in terminal?
The names of the .txt files in my directory are numbered sequentially: 1.txt, 2.txt, etc.
Thanks!

GNU sed:
sed -i 's/--/—/g' *.txt
OSX BSD sed:
You need to specify a backup file extension. To create a backup file with the extension: .txt.bak:
sed -i '.bak' 's/--/—/g' *.txt
To completely replace the files, specify an empty extension:
sed -i '' 's/--/—/g' *.txt

sed -i 's/--/–/g' *.txt ought to work. The -i flag to sed makes it act on the files in-place, the s stands for substitute, and the g makes it replace multiple occurrences of the pattern on the same line. Look up sed's documentation for more information.
EDIT: This works on GNU/Linux; it turns out that the syntax is slightly different on OSX (see comments and accepted answer).

Related

Pipe last 11 characters in filename to a text file

Have a directory full of file names that end with .mp3 and have a code in it that i would like to pipe into a text file.
I need to get the last 11 characters before the .mp3 part of a file in a certain directory and pipe that into a text file (with bash on mac osx)
How do I accomplish this? With sed?
If I'm understanding correctly, you have a list of files with names like "abcdefghijklmnopqrstuvwxyz.mp3" and want to extract "pqrstuvwxyz". You can do this directly in bash without invoking any fancy sed business:
for F in *.mp3; do STRIP=${F/.mp3}; echo ${STRIP: -11}; done > list.txt
The first STRIP variable is the name of each file F with the .mp3 extension removed. Then you echo the last 11 characters and save to a file.
There's a nice page on bash substitutions here. sed is great but I personally find it's overkill for these simple cases.
Along with good above answers, can be done via awk
for f in `ls *.mp3`;
echo $f|awk -F. '{printf substr($1,length($1)-11,length($1)),$2;}'
done

Mac OS X remove line from multiple files

I'm attempting to remove a line from several hundred files. The following does exactly what I need but, it doesn't save changes (as expected).
$ grep -v meow src/files
I've seen that appending > to the end of a given command will specify where the output buffer should save but, does this work for multiple files?
So I'd like to know if there's an elegant way to mass edit via the terminal. All of the examples I've come across using awk or sed only provide solutions for editing one file at a time.
One way to do this is using the following Perl one-liner:
perl -i.bak -n -e 'print unless /meow/' src/files
This should do in-place editing of multiple files. The originals are saved in .bak files.
Another way to do it is to do a similar operation with sed:
sed -i .bak '/meow/d' src/files/*
Perl got its -i option from sed, after all. Note that to use no backup file, you need an explicit empty extension with at least some versions of sed:
sed -i '' '/meow/d' src/files/*

sed won't delete what I want [duplicate]

This question already has answers here:
Find and replace in file and overwrite file doesn't work, it empties the file
(12 answers)
Sed to delete a range of lines from a specific match line TILL a specific match line (not including last line)
(3 answers)
Closed 8 years ago.
I am writing a bash shell script, and in it I am trying to delete lines from a text file between 2 markers
START
...
...
END
Do eliminate this I have tried a few things, and every time it leave my text file blank.
sed '/START/,/END/d' myfile.txt > myfile.txt
sed '/START/d' myfile.txt > myfile.txt
As long as I have a sed command in my code, my entire file gets erased and not just the section I am looking to erase.
You are redirecting stdout to the same file as stdin. When you do this, your redirection is interpreted buy the shell and it opens a new file for write with that name. Your existing file is overwritten by the newly created blank file. You will need to redirect the output to a different file or you can edit the file by using the -i option to sed.
You can't redirect to a file that you are reading. That will delete your file's contents, as you've noticed.
Instead, either redirect to a different file, or edit in place:
sed -i ... myfile.txt
A way in awk.
awk '/START/{x=1}/END/{x=0}!x{print > ARGV[1]}' myfile.txt
Portable
awk '/START/{x=1}/END/{x=0}!x{print > "myfile.txt"}' myfile.txt

How will i use sed shell script for replacing a pattern in a list of file

I have some 100 files which have my name in it, RAHUL. I want it replaced with another term RAHUL2. I have a file which contains the list of files and i want to fetch it in a sed to do the changes.
files :
C:/desktop/file1.txt
C:/desktop/rahul/file1.txt
C:/desktop/rahul/file3.txt
C:/desktop/rahul/file4.txt
C:/desktop/rahul/file6.txt
C:/desktop/rahul/file8.txt
C:/desktop/rahul/file9.txt
and in each file data, i want to replace all occurance of term RAHUL with RAHUL2
I assume you are using some Cygwin environment on Windows, since you have sed. Then you can use find to list all the files and execute sed on them:
find C:/desktop -type f -name 'file*.txt' -exec sed -i 's/RAHUL/RAHUL2/g' {} \;
Please make a backup of the original files if you are using sed -i but aren't sure if the command is working already. This because sed -i will overwrite the original file. You have been warned.
hek2mgl's answer is good if you want to search for all files matching file*.txt pattern on your C:/desktop directory.
Now as you already have a file containing the list of files to edit, here is another way to proceed:
while read FILE ; do sed -i 's/RAHUL/RAHUL2/g' $FILE ; done < files_to_edit.txt
The read command will read your input one line after another. Input is files_to_edit.txt file, as indicated by the < input redirection operator.
Remark about -i option remains valid: it will edit your files in place, so make backup, or at least run it first on a couple of files (potentially without -i option, just to check what output is).

Search a string in a file and delete it from this file by Shell Script [duplicate]

This question already has answers here:
How to delete from a text file, all lines that contain a specific string?
(21 answers)
Closed 5 years ago.
I want to delete a line containing a specific string from the file. How can I do this without using awk? I tried to use sed but I could not achieve it.
This should do it:
sed -e s/deletethis//g -i *
sed -e "s/deletethis//g" -i.backup *
sed -e "s/deletethis//g" -i .backup *
it will replace all occurrences of "deletethis" with "" (nothing) in all files (*), editing them in place.
In the second form the pattern can be edited a little safer, and it makes backups of any modified files, by suffixing them with ".backup".
The third form is the way some versions of sed like it. (e.g. Mac OS X)
man sed for more information.
sed -i '/pattern/d' file
Use 'd' to delete a line. This works at least with GNU-Sed.
If your Sed doesn't have the option, to change a file in place, maybe you can use an intermediate file, to store the modification:
sed '/pattern/d' file > tmpfile && mv tmpfile file
Writing directly to the source doesn't work: sed '/pattern/d' FILE > FILE so make a copy before trying out, if you doubt it. The redirection to a new file FILE will open a new file FILE before reading from it, so reading from it will result in an empty input.
Try the vim-way:
ex -s +"g/foo/d" -cwq file.txt

Resources