bash - replacing string with sed - bash

For some mysterious reason, some elements in my CSV data appear as s/stWgvN52??f2& ?" instead of stWgvN522tw0JtZZnyXj, which messes up the file because I have ; set as the CSV delimiter.
I attempted to replace the defective string using sed as follows:
$ sed -i 's/stWgvN52??f2& ?"/stWgvN522tw0JtZZnyXj/g' file.csv
but I get the following error:
sed: 1: "access_logs_2014-04.csv": command a expects \ followed by text
What is the reason?

When you use the -i option, you have to specify the extension of the backup file that gets made. Some versions of sed expect the extension directly appended to the -i option, so what you wrote would work. But other versions (like the version on OS X) require it to be a separate option, so you have to write:
sed -i '' 's/stWgvN52??f2& ?"/stWgvN522tw0JtZZnyXj/g' file.csv
to specify that you don't want a backup file.

Related

How to remove first 3 lines of multiple .md files with Mac terminal?

I need to remove first three lines of multiple markdown files structured like that:
|- Folder
| - 01-07-22.md
| - 02-07-22.md
| - 03-07-22.md
| - ...
I would like to do this with Mac Terminal (if possible) because I have no expertise with any coding language and thus I don't have any coding platform installed on my computer.
Also I would like to know if other than deleting first 3 lines is possible to add "##" at the very beginning of every document.
What works:
This work:
sed -i '' '1,3d' Folder/*.md
The following command works also:
sed -i '' '1i\
##' *.md
But it does not add a new line before the first line.
This does not work at all:
sed -i '' '1s
/^/##/' *.md
How to add an empty line at the beginning and "##" at the beginning of the now second line? Explaination:
From this:
# First line of example .md file
Second line of example .md
...
To this:
### First line of example .md file
Second line of example .md
...
You should be able to use (GNU) sed. I hope that the Mac version supports all the required flags and features.
To delete the first 3 lines:
sed -i '1,3d' Folder/*.md
To prepend the line ## to every file:
sed -i '1i##' Folder/*.md
To prefix the existing first line with ##:
sed -i '1s/^/##/' Folder/*.md
The original files are overwritten without confirmation, but you can specify -i.bak to create backup files, e.g. Folder/01-07-22.md.bak. Specify -i '' to disable backup file creation.
Certain sed implementations might always require an argument after -i, so go with -i.bak or -i .bak.
If prepending a line does not work, try a different syntax (the newline is important):
sed -i .bak '1i\
##' Folder/*.md
If that doesn't work either, there's another form how sed could be invoked:
sed -i .bak -e '1i\' -e '##' Folder/*.md
If you want to modify the first line and add an empty line before it, e.g. transforming
1
2
3
into
##1
2
3
would require you to use the following command:
sed -i .bak '1s/^/##/;1i\
' Folder/*.md

Increment a variable in a .txt file with bash

I'm trying to change a variable in a .txt file but I can't figure how. I've looked on internet and tried what was written but it doesn't work. I get the following error message :
sed: 1: "abc.txt": command a expects \ followed by text
Here was what I originally tried to run:
sed -i 's/Hi/Good Morning/' abc.txt
Check your man page for sed. -i probably requires a suffix argument.
-i extension
Edit files in-place, saving backups with the specified extension. If a zero-length extension is given,
no backup will be saved. It is not recommended to give a zero-length extension when in-place editing
files, as you risk corruption or partial content in situations where disk space is exhausted, etc.
What's happening is that sed is taking 's/Hi/Good Morning/' to be the argument to -i, and then considering abc.txt to be the sed command itself.
By adding a proper backup extension to the command, it will work like so:
$ cat abc.txt
Hi, How are you
$ sed -i .bak 's/Hi/Good Morning/' abc.txt
$ cat abc.txt
Good Morning, How are you
$ cat abc.txt.bak
Hi, How are you

Replacing the file name which comes with # (Hash) using sed

I facing some problem with replace the file name mixed with #
Ex:- #test#123
i have maintaining the report file like report.csv, Im using the bash script to summarize my report.
by default my report.csv file comes with all extension type as a default template.
Inside my report.csv
DATE-COPY COPY_STATUS NO_TXT NO_ERR NO_SQL
if my copy success i will replace using sed from COPY_STATUS to COPY_SUCCESS
if its normal file(/home/user/text123.txt) is copied i dont have problem with replacing path
sed 1s#NO_TXT#/home/user/text123.txt# -i report.csv
after that my csv file will look
DATE-COPY COPY_SUCCESS /home/user/text123.txt NO_ERR NO_SQL
if i have # hashmixed file
example
sed 1s#NO_TXT#/home/user/#text#123.txt# -i report.csv
i get like below error and unable to replace hash files with full path
sed: -e expression #1, char 44: unknown option to `s'
Sed can use a number of characters for its separator. Most commonly a / is used, however for files it's handy to use another character such as #, as you have done. In your instance, the simplest approach would be to use another separator such as |, but ensure you quote your sed string:
sed '1s|NO_TXT|/home/user/#text#123.txt|' -i report.csv
Or if you are passing in a variable, use double quotes:
sed "1s|NO_TXT|/home/user/$file|" -i report.csv

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 gives "sed: 1: "tsunit.js": undefined label 'sunit.js'"

Short questing, why does this line
sed -i '1s/^/#!\/usr\/bin\/env node\n/' tsunit.js;\
Give me this error
sed: 1: "tsunit.js": undefined label 'sunit.js'
in a Makefile, if relevant.
I’m on a Mac.
According to the Apple man page for sed, the -i option takes a required argument specifying the file extension for the backup file. As a result, assuming that you are on a Mac or similar, sed believes that you intended '1s/^/#!\/usr\/bin\/env node\n/' to be the file extension of the backup. It then interprets tsunit.js as a sed command. the leading t tells sed to branch to the label sunit.js which, of course, doesn't exist. Hence the error message.
The solution is:
sed -i '.bak' '1s/^/#!\/usr\/bin\/env node\n/' tsunit.js
Or, if you really do not want a backup:
sed -i '' '1s/^/#!\/usr\/bin\/env node\n/' tsunit.js
Also, it looks like you're inserting a line. sed has more commands than s
sed -i "" '1i\
#!/usr/bin/env node' tsunit.js

Resources