Remove filenames from Textfile with sed - bash

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.

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.

What is wrong with this sed command?

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.

Replacing with sed wont work

I have a file called "washington", with capital spelled in 4 different
ways: Capital, capital, Capitol, capitol. Use the "sed" command
to replace all of them at once, with the correct spelling: capital.
I tried cat /washington | s '/[Cc]apit[ao]l/capital' but it wont work.
What do i do?
This will work:
$ cat /washington | sed 's/[Cc]apit[ao]l/capital/g'
Note that you need proper command in quotes. Starts with 's' for 'substitute' and ends with 'g' for 'global'. Global means replace all occurrences in the string.
sed 's/[Cc]apit[ao]l/capital/g' <filename>
If you want to change the file itself, i.e. write back to file
sed -i 's/[Cc]apit[ao]l/capital/g' <filename>
If you want to keep a backup (my suggestion) of the original file
sed -i.bak 's/[Cc]apit[ao]l/capital/g' <filename> will keep a backup named .bak
(See, i did not use cat anywhere)

Why does sed add a new line in OSX?

echo -n 'I hate cats' > cats.txt
sed -i '' 's/hate/love/' cats.txt
This changes the word in the file correctly, but also adds a newline to the end of the file. Why? This only happens in OSX, not Ubuntu etc. How can I stop it?
echo -n 'I hate cats' > cats.txt
This command will populate the contents of 'cats.txt' with the 11 characters between the single quotes. If you check the size of cats.txt at this stage it should be 11 bytes.
sed -i '' 's/hate/love/' cats.txt
This command will read the cats.txt file line by line, and replace it with a file where each line has had the first instance of 'hate' replaced by 'love' (if such an instance exists). The important part is understanding what a line is. From the sed man page:
Normally, sed cyclically copies a line of input, not including its
terminating newline character, into a pattern space, (unless there is
something left after a ``D'' function), applies all of the commands
with addresses that select that pattern space, copies the pattern
space to the standard output, appending a newline, and deletes the
pattern space.
Note the appending a newline part. On your system, sed is still interpreting your file as containing a single line, even though there is no terminating newline. So the output will be the 11 characters, plus the appended newline. On other platforms this would not necessarily be the case. Sometimes sed will completely skip the last line in a file (effectively deleting it) because it is not really a line! But in your case, sed is basically fixing the file for you (as a file with no lines in it, it is broken input to sed).
See more details here: Why should text files end with a newline?
See this question for an alternate approach to your problem: SED adds new line at the end
If you need a solution which will not add the newline, you can use gsed (brew install gnu-sed)
A good way to avoid this problem is to use perl instead of sed. Perl will respect the EOF newline, or lack thereof, that is in the original file.
echo -n 'I hate cats' > cats.txt
perl -pi -e 's/hate/love/' cats.txt
Note that GNU sed does not add the newline on Mac OS.
Another thing you can do is this:
echo -n 'I hate cats' > cats.txt
SAFE=$(cat cats.txt; echo x)
SAFE=$(printf "$SAFE" | sed -e 's/hate/love/')
SAFE=${SAFE%x}
That way if cats.txt ends in a newline it gets preserved. If it doesn't, it doesn't get one added on.
This worked for me. I didn't have to use an intermediate file.
OUTPUT=$( echo 'I hate cats' | sed 's/hate/love/' )
echo -n "$OUTPUT"

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