sed - remove dates from each line of file - bash

I am trying to get rid of the dates - all of them from 2015 -present 2017.
I want to rename each foo_data_$date to just foo_data_*. I just need the files name. Not all the individual dates.
I do not understand the regex for sed - I can do it in perl with perl -nle 'print /(foo_data_)\d+txt) but can't figure out how to do it with sed.
I want to do it in sed because I have been using sed -i flag and changing the file in place.
cat /tmp/foo | head | sed -e 's/foo_data_20*txt/foo_data_\*/g'
foo_data_20150901.txt
foo_data_20150902.txt
foo_data_20150906.txt
foo_data_20150907.txt
foo_data_20150908.txt
foo_data_20150909.txt
foo_data_20150912.txt

You can just run sed like this.
sed -e 's/foo_data_[0-9]*/foo_data_/g'
Now, for the thing to capture dates only between 2015 and 2017, this will make it.
sed -e 's/foo_data_201\(5\|6\|7\)[0-9]*/foo_data_/g'
Then you will remove the dates from the file names in your file.

You don't need to mention foo_data:
sed -i 's/201[567][01][0-9][0-3][0-9]//'
Your command was wrong: /foo_data_20*txt/ will match a '0' 0 or more times (something like foo_data_2000000000000txt).

If you just want to rename the files, most Linux distros (assuming you're on Linux) have a rename utility that handles Perl regular expressions just fine:
pax> touch pax_100.txt ; touch pax_200.txt
pax> rename -n 's/_(\d)/_diablo_$1/' pax*
rename(pax_100.txt, pax_diablo_100.txt)
rename(pax_200.txt, pax_diablo_200.txt)
The -n options shows what will happen rather than doing the rename. Once you're satisfied, simply remove it.
Oh, and one final note. If you remove the dates from all those file names, they'll all have the same file name. Unless your file names are just test data, that's probably going to need some further thought on your part.

Related

Sed command works with pipe but gives error when the input is a file [duplicate]

Imagine the following data stored in file data.txt
1, StringString, AnotherString 545
I want to replace "StringString" with "Strung" with the following code
sed -ir 's/String+/Strung/g' data.txt
But it won't work. This works though:
sed -ri 's/String+/Strung/g' data.txt
I don't see any reason why the order of option flags would matter. Is it a bug or is there an explanation?
Please note that I'm not looking for a workaround but rather why the order of -ir and -ri matters.
Sidenotes: The switch -i "edits the file in place" while -r allows "extended regular expression" (allowing the + operator). I'm running sed 4.2.1 Dec. 2010 on Ubuntu 12.10.
When doing -ir you are specifying that "r" should be the suffix for the backup file.
You should be able to do -i -r if you need them in that order
Did you check sed --help or man sed?
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied).
The default operation mode is to break symbolic and hard links.
This can be changed with --follow-symlinks and --copy.

Find two string in same line and then replace using sed

I am doing a find and replace using sed in a bash script. I want to search each file for words with files and no. If both the words are present in the same line then replace red with green else do nothing
sed -i -e '/files|no s/red/green' $file
But I am unable to do so. I am not receiving any error and the file doesn't get updated.
What am I doing wrong here or what is the correct way of achieving my result
/files|no/ means to match lines with either files or no, it doesn't require both words on the same line.
To match the words in either order, use /files.*no|no.*files/.
sed -i -r -e '/files.*no|no.*files/s/red/green/' "$file"
Notice that you need another / at the end of the pattern, before s, and the s operation requires / at the end of the replacement.
And you need the -r option to make sed use extended regexp; otherwise you have to use \| instead of just |.
This might work for you (GNU sed):
sed '/files/{/no/s/red/green/}' file
or:
sed '/files/!b;/no/s/red/green/' file
This method allows for easy extension e.g. foo, bar and baz:
sed '/foo/!b;/bar/!b;/baz/!b;s/red/green/' file
or fee, fie, foe and fix:
sed '/fee/!b;/fi/!b;/foe/!b;/fix/!b;s/bacon/cereal/' file
An awk verison
awk '/files/ && /no/ {sub(/red/,"green")} 1' file
/files/ && /no/ files and no have to be on the same line, in any order
sub(/red/,"green") replace red with green. Use gsub(/red/,"green") if there are multiple red
1 always true, do the default action, print the line.

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.

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/*

Issue with reformatting a date using sed

I'm working on a shell script to reformat a CSV file exported from Access into a format that can be imported more easily into MySQL.
There's a number of different operations I need to perform on the file, and I'm currently stuck on one of them. I've used sed and awk a bit before, but I'm not great with them (I'm used to PCRE), and I'm at a loss to figure out where I've gone wrong here.
The command I've written is as follows:
sed -e '1d' raw.csv | sed 's/£//g' | sed 's/ 00:00:00//g' | sed 's/\([0-9]{2}\)\/\([0-9]{2}\)\/\([0-9]{2}\)/20\3-\1-\2/g' > formatted.csv
Now, the operations I carry out here are as follows:
Delete the first line
Remove all pound signs
Remove all unwanted instances of 00:00:00
Reformat the date from mm/dd/yy to yyyy-mm-dd
I've worked my way through these in order and they work as expected, except for the last one:
sed 's/\([0-9]{2}\)\/\([0-9]{2}\)\/\([0-9]{2}\)/20\3-\1-\2/g' > formatted.csv
Can anyone see where I've gone astray?
You'll need to escape the curly brackets too.
sed 's/\([0-9]\{2\}\)\/\([0-9]\{2\}\)\/\([0-9]\{2\}\)/20\3-\1-\2/g' > formatted.csv

Resources