What is wrong with this sed command? - bash

I am facing a strange problem. An answer to what I want to do already exists Here. I am trying to remove trailing commas from each line of a file containing thousands of lines. Like this -
This is my command -
sed -i 's/,*$//g' file_name.csv
However, the output I get is exactly the same as the image above and the trailing commas are not removed.
I think SED is not matching the pattern and thus failing to replace the commas. To check if there are any hidden characters in the file, I used VIM's :set list option -
There are only $ at the end of each line which is just what is expected.
I can't understand why the command is failing.

I can suggest you two options:
First One is my favorite.
dos2unix file
#####will work for Huge File also
then try to run the command.
Other way to do this:
cat file | tr -d '\r' > file
###may not work for huge file
then run the command.
tr -d '\r' < file > file.tmp ; mv file.tmp file
##will work for Huge File also
Thanks to #Nahuel for suggesting last command.

Related

Renaming filename before first occurrence of character

I'm trying to rename a batch of files using a bash script or just in the command line but can't seem to find anything on how to remove characters before the first occurrence of a character.
Right now my files are named:
author1_-_year_-_title_name.txt
author2_-_year_-_title_name.txt
And I want them to look like
_-_year_-_title_name.text
or even
year_-_title_name.text
I've tried sed in the command line:
sed 's/^[^_-_]* _-_ //' *
but this only tried to edit the text files, not the file name
You can't change filenames using sed. Try this simple loop instead:
for fp in ./*_-_*; do
echo mv "$fp" "${fp#*_-_}"
done
If the output looks good, remove echo.
Could you please try rename command as follows.
rename -n s/[^-]*-_// *.txt
Output will be as follows.
rename(author1_-_year_-_title_name.txt, year_-_title_name.txt)
rename(author2_-_year_-_title_name.txt, year_-_title_name.txt)
Once you are Happy with above results(which will print only on terminal) remove -n option in above command and it should rename the files.

How to use sed on macOS to replace a line with bash script

I am on macOS High Sierra, and I've had a few issues with sed,
after spending a day on Google and this site, I've honestly tried everything I could think of and was suggested.
I have an example.txt file with 3 lines.
line1
line2
line3
The 3 lines can be anything, I do not know them upfront. (scenario)
And at some point I do know what the line is going to be.
All I wish to achieve is to use 'whatever' onliner that basically says:
in that file, replace line 2, with the new data.
sed -i "2s/.*/$NEW_DATA/" "$FILENAME"
This should work, but on macOS, this does not.
sed -ie "2s/.*/$NEW_DATA/" "$FILENAME"
Note the e? Someone on here suggested to add an e, and yes, that works.. but it means it adds the e behind the .txt. I end up with 2 files, example.txt and example.txte
sed -i'' "2s/.*/$NEW_DATA/" "$FILENAME"
Note the '' behind -i, and yes, without a space? This should work too.
It doesn't, it will complain that command c requires \
I could go on, but the request is quite simple:
on macOS, in a bash shell script, how do I simply replace a specified line of text in a .txt file, with a completely new line of text -- not knowing what the line of text was before?
If this can be a simple macOS one liner with awk or whatever, that's fine. It doesn't have to be sed. But when I search this site, it seems to be the recommended one to go with in this regards.
From the sed man page in macOS:
-i extension
Edit files in-place, saving backups with the specified extension.
If a zero-length extension is given, no backup will be saved.
Therefore this can be used to replace line 2 without keeping backup:
sed -i '' "2s/.*/$NEW_DATA/" testfile.txt
If the goal is just to replace contents of line 2 awk could also be used, for example:
awk 'NR==2{$0="your content"}1' testfile.txt > testfile.tmp && mv testfile.tmp testfile.txt

Remove filenames from Textfile with sed

I would like to delete filenames from a textfile to have as output only the folder.
Example:
Creature\FrostwolfPup\FrostWolfPup_Shadow.m2
Creature\FrostwolfPup\FrostWolfPup_Fire.m2
To
Creature\FrostwolfPup\
To match only the Filenames i use [^\\]*$
Now i put it together with sed while /d should delete it
D:\filetype\core\sed.exe -n -e "/^[^\\]*$/d" D:\filetype\listfile\archive\tmp\all.txt > D:\filetype\module\model_bruteforce\tmp\folders_tmp1.txt
But instead of a textfile with my folders i got only a empty textfile as output, and so something must be wrong.
Tested on linux, not cygwin
sed -r 's/[^\\]*$//g' /path/to/original/file > /path/to/new/file
Try:
sed.exe -e "s/[^\\]*$//" path/to/folders.txt
The command s/[^\\]*$// asks sed to remove everything after the last \ on a line to the end of the line.
Caveat: since I don't have a windows machine handy for testing, I am unsure if the backslashes need to be doubled as shown above.
Discussion
-n tells sed not print anything unless we explicitly ask it to. The following command never asks sed to print:
sed.exe -n -e "/^[^\\]*$/d"
Consequently, it produces no output.

Corrupt playlists missing some newlines, how do I add them?

The problem I have is that some big playlists of mine contain some lines that are missing a newline.
What I want to do is parse the file and insert \n before /run/ if there is no new line. I tried:
text=$(< *.m3u)
text=${text//$'/run/}'/$'\n\n\r/run/}'}
printf "%s\n" "$text" > file.m3u
but it doesn't appear to work. I have tried some other approaches but they all fail, so I'm thinking perhaps I am missing something very obvious and basic.
OK line:
/run/.../../.. .../hippho.mp3
Defective line:
/run/.../../.. .../holla.amigo.mp3/run/.../../.. .../dodoh.mp3
In response to the first reply, this
sed -e 's#/run/#\n/run/#g' *.m3u > PLAYLIST
gives me a file with many \n\n/run/. I tried to fix it with
sed -e ':a;N;$!ba;s/\n\n/\n/g;p' PLAYLIST > PLAYLIST1
which removes them, but instead lists all files twice -- why is that?
My fix to remove the second listing of the files:
playlist='PLAYLIST1'
split -a 1 -d -n l/2 $playlist $playlist
cp PLAYLIST10 PLAYLIST
This finally gives me what I want, but there must be prettier ways.
there was.
sed -e 's#(.)/run/#\1\n/run/#g' *.m3u
does it all thanks tripleee
This uses sed, not bash, and does add a new line at beginning of file.
sed -e 's#/run/#\n/run/#g' *.m3u

Trying to delete lines from file with sed -- what am I doing wrong?

I have a .csv file where I'd like to delete the lines between line 355686 and line 1048576.
I used the following command in Terminal (on MacOSx):
sed -i.bak -e '355686,1048576d' trips3.csv
This produces a file called trips3.csv.bak -- but it still has a total of 1,048,576 lines when I reopen it in Excel.
Any thoughts or suggestions you have are welcome and appreciated!
I suspect the problem is that excel is using carriage return (\r, octal 015) to separate records, while sed assumes lines are separated by linefeed (\n, octal 012); this means that sed will treat the entire file as one really long line. I don't think there's an easy way to get sed to get sed to recognize CR as a line delimiter, but it's easy with perl:
perl -n -015 -i.bak -e 'print if $. < 355686 || $. > 1048576' trips3.csv
(Note: if 1048576 is the number of "lines" in the file, you can leave off the || $. > 1048576 part.)
Not sure about the osx sed implementation, however the gnu sed implementation when passed the -i flag with a backup extension first copies the original file to the specified backup and modifies the original file in-place. You should expect to see a reduced number of lines in the original file trip3.csv
Some incantation that should do the job (if you have Ruby installed, obviously)
ruby -pe 'exit if $. > 355686' < trips3.csv > output.csv
If you prefer Perl/Python, just follow the documentation to do something similar and you should be fine. :)
Also, I'm using one of the Ruby one-liners, by Dave.
EDIT: Sorry, forgot to say that you need '> output.csv' to redirect stdout to a file.
awk '!(NR>355686 && NR <1048576)' your_file

Resources