I have php.ini with memory_limit = 128M
I would like to replace this with sed command.
I had try this, and it does not work
sed -i '' 's/memory_limit\s*=\s*\d*M/memory_limit = 1024M/g' ~/Desktop/php.ini
any idea why?
I copy it to desktop so it does not tinker the original one before it actually working
I have modified your regex a little, also removed your empty single strings and it's working fine to me.
I changed this:
sed -i '' 's/memory_limit\s*=\s*\d*M/memory_limit = 1024M/g' ~/Desktop/php.ini
To this:
sed -i 's/memory_limit\s*=.*/memory_limit=1024M/g' ~/Desktop/php.ini
Regex change here--^^
Console output
$ cat php.ini
asdfasd
memory_limit = 128M
fasd
$ sed -i 's/memory_limit\s*=.*/memory_limit=1024M/g' ~/php.ini
$ cat php.ini
asdfasd
memory_limit=1024M
fasd
Btw, my sed version is sed (GNU sed) 4.2.2
The BSD sed on Mac OS X does not recognize \s as space and \d as digit even with the -E option:
$ echo 'memory_limit = 128M' | sed -E 's/memory_limit\s*=\s*\d*M/memory_limit = 1024M/g'
memory_limit = 128M
$ # Oops - output is the same as the input!
I didn't manage to create an input string that is recognized by the s/// you show, with or without the -E option (which surprises me a little; I tried a fair number of variations). However, the substitution you require can be done portably and easily with:
$ echo 'memory_limit = 128M' |
> sed 's/memory_limit[[:space:]]*=[[:space:]]*[[:digit:]]*M/memory_limit = 1024M/g'
memory_limit = 1024M
$
Fixing that so it does the in-place edit of the file without any backup (I hope you have the file under some sort of configuration management!) is a trivial combination of what I wrote and what you wrote.
If you use -i.bak (creating a backup; no space between -i and .bak), then the script will work with GNU sed as well as BSD sed. If you don't do the overwriting, then it will work with any POSIX-compliant sed.
This solution will work on OSX:
sed -Ei '' 's/(memory_limit = )[0-9]+M/\11024M/g' ~/Desktop/php.ini
i key for edit file in-place
E key for extended regex
'' need to supply when no .bak (backup) specified
s substitute pattern with
()defining a group
\1 group reference
[0-9]+M - any digit with M at the end
g - substitute all occurrences of the pattern
It's always good to save backup file:
sed -i .bak -E 's/(memory_limit = )[0-9]+M/\11024M/g' php.ini
This will save you a copy of php.ini before substitution to php.ini.bak
Related
I want to remove all the non-ASCII characters from a file in place.
I found one solution with tr, but I guess I need to write back that file after modification.
I need to do it in place with relatively good performance.
Any suggestions?
A perl oneliner would do: perl -i.bak -pe 's/[^[:ascii:]]//g' <your file>
-i says that the file is going to be edited inplace, and the backup is going to be saved with extension .bak.
# -i (inplace)
sed -i 's/[\d128-\d255]//g' FILENAME
I tried all the solutions and nothing worked. The following, however, does:
tr -cd '\11\12\15\40-\176'
Which I found here:
https://alvinalexander.com/blog/post/linux-unix/how-remove-non-printable-ascii-characters-file-unix
My problem needed it in a series of piped programs, not directly from a file, so modify as needed.
sed -i 's/[^[:print:]]//' FILENAME
Also, this acts like dos2unix
Try tr instead of sed
tr -cd '[:print:]' < file.txt
# -i (inplace)
LANG=C sed -i -E "s|[\d128-\d255]||g" /path/to/file(s)
The LANG=C part's role is to avoid a Invalid collation character error.
Based on Ivan's answer and Patrick's comment.
This worked for me:
sed -i 's/[^[:print:]]//g'
I'm using a very minimal busybox system, in which there is no support for ranges in tr or POSIX character classes, so I have to do it the crappy old-fashioned way. Here's the solution with sed, stripping ALL non-printable non-ASCII characters from the file:
sed -i 's/[^a-zA-Z 0-9`~!##$%^&*()_+\[\]\\{}|;'\'':",.\/<>?]//g' FILE
As an alternative to sed or perl you may consider to use ed(1) and POSIX character classes.
Note: ed(1) reads the entire file into memory to edit it in-place, so for really large files you should use sed -i ..., perl -i ...
# see:
# - http://wiki.bash-hackers.org/doku.php?id=howto:edit-ed
# - http://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes
# test
echo $'aaa \177 bbb \200 \214 ccc \254 ddd\r\n' > testfile
ed -s testfile <<< $',l'
ed -s testfile <<< $'H\ng/[^[:graph:][:space:][:cntrl:]]/s///g\nwq'
ed -s testfile <<< $',l'
awk '{ sub("[^a-zA-Z0-9\"!##$%^&*|_\[](){}", ""); print }' MYinputfile.txt > pipe_out_to_CONVERTED_FILE.txt
I appreciate the tips I found on this site.
But, on my Windows 10, I had to use double quotes for this to work ...
sed -i "s/[\d128-\d255]//g" FILENAME
Noticed these things ...
For FILENAME the entire path\name needs to be quoted
This didn't work -- %TEMP%\"FILENAME"
This did -- %TEMP%\FILENAME"
sed leaves behind temp files in the current directory, named sed*
I have a bunch of txt-files containing stuff like this:
text_i_need_to_remove{text_i_need_to_retain}
text_i need_to_remove{text_i_need_to_retain}
...
How do I remove text before curly braces (and curly braces themselves) and retain just only text_i_need_to_retain?
Deleting everything upto { or } at end of line
:%s/.*{\|}$//g
From bash shell, you can use text processing tools like sed and awk. Assume file is named ip.txt
1) With sed, which is pretty similar to regex we used inside vim. The -i flag allows to make change in place, i.e it modifies the input file itself.
$ sed -i 's/.*{\|}$//g' ip.txt
2) With awk, one can again use substitution or in this case, split the line on curly brackets and use only the second column.
$ awk -F'{|}' '{print $2}' ip.txt > tmp && mv tmp ip.txt
If you have GNU awk, there is -i inplace option for in place editing
$ gawk -i inplace -F'{|}' '{print $2}' ip.txt
To make changed to all files in current directory, use
sed -i 's/.*{\|}$//g' *
Or if they have common extension, say .txt, use
sed -i 's/.*{\|}$//g' *.txt
:%s/^.*{\(.*\)}$/\1/ or in bash, sed 's/^.*{\(.*\)}$/\1/ foo.txt
\(.*\) is a control group which feeds into \1 and looks like a lumbering zombie.
you can use this in vim;
:%s/^.*{// | %s/}$//
you can also use this script; first run this, if everythink is ok, uncomment sed with -i option as below;
#!/bin/bash
for item in $(ls /dir/where/my/files/are)
do
sed -i 's/^.*{//;s/}$//' /dir/where/my/files/are/$item
done
sed -i ; inplace replace
or
Only use as below;
sed -i 's/^.*{//;s/}$//' /dir/where/my/files/are/*
Perl can be used to do the substitution on all files:
perl -i -pe 's/.*{|}$//g' *.txt
I have a file with strings similar to this:
abcd u'current_count': u'2', u'total_count': u'3', u'order_id': u'90'
I have to find current_count and total_count for each line of file. I am trying below command but its not working. Please help.
grep current_count file | sed "s/.*\('current_count': u'\d+'\).*/\1/"
It is outputting the whole line but I want something like this:
'current_count': u'3', 'total_count': u'3'
It's printing the whole line because the pattern in the s command doesn't match, so no substitution happens.
sed regexes don't support \d for digits, or x+ for xx*. GNU sed has a -r option to enable extended-regex support so + will be a meta-character, but \d still doesn't work. GNU sed also allows \+ as a meta-character in basic regex mode, but that's not POSIX standard.
So anyway, this will work:
echo -e "foo\nabcd u'current_count': u'2', u'total_count': u'3', u'order_id': u'90'" |
sed -nr "s/.*('current_count': u'[0-9]+').*/\1/p"
# output: 'current_count': u'2'
Notice that I skip the grep by using sed -n s///p. I could also have used /current_count/ as an address:
sed -r -e '/current_count/!d' -e "s/.*('current_count': u'[0-9]+').*/\1/"
Or with just grep printing only the matching part of the pattern, instead of the whole line:
grep -E -o "'current_count': u'[[:digit:]]+'
(or egrep instead of grep -E). I forget if grep -o is POSIX-required behaviour.
For me this looks like some sort of serialized Python data. Basically I would try to find out the origin of that data and parse it properly.
However, while being hackish, sed can also being used here:
sed "s/.*current_count': [a-z]'\([0-9]\+\).*/\1/" input.txt
sed "s/.*total_count': [a-z]'\([0-9]\+\).*/\1/" input.txt
I have this sed command for removing the spaces after commas.
sed -e 's/,\s\+/,/g' example.txt
How can i change it that, it will make the modification between only specific line numbers.
(e.g. between second and third lines).
Use:
sed '2,3s/,\s\+/,/g' example.txt
This will apply the regex /,\s\+/ only in the lines numbered 2 to 3 (inclusive) and substitute the match with ,.
Since OSX (BSD sed) has some syntax differences to linux (GNU) sed, thought I'd add the following from some hard-won notes of mine:
OSX (BSD) SED find/replace within (address) block (start and end point patterns(/../) or line #s) in same file (via & via & via & section 4.20 here):
Syntax:
$ sed '/start_pattern/,/end_pattern/ [operations]' [target filename]
Standard find/replace examples:
$ sed -i '' '2,3 s/,\s\+/,/g' example.txt
$ sed -i '' '/DOCTYPE/,/body/ s/,\s\+/,/g' example.txt
Find/replace example with complex operator and grouping (cannot operate without grouping syntax due to stream use of standard input). All statements in grouping must be on separate lines, or separated w/ semi-colons:
Complex Operator Example (will delete entire line containing a match):
$ sed -i '' '2,3 {/pattern/d;}' example.txt
Multi-file find + sed:
$ find ./ -type f -name '*.html' | xargs sed -i '' '/<head>/,/<\/head>/ {/pattern/d; /pattern2/d;}'
Hope this helps someone!
sed -e '2,3!b;s/,\s\+/,/g' example.txt
This version can be useful if you later want to add more commands to process the desired lines.
I have a file, cache.md, that starts off like this:
# 2012-05-09.8271
CACHE MANIFEST
CACHE:
/index.html
I'm trying to write a shell script (using Automator in OS X Lion) to replace the first line and change the text (after the hash) to today's date, a dot, and a random number.
Here's the bash script I have so far, but it doesn't do anything.
_now=$(date +"%Y-%m-%d")
_rand=$RANDOM
sed -i '' '1 s/[\d\-\.]+/$_now.$_rand/' ~/Desktop/cache.mf
Use this sed command:
sed -i '' '1 s/^#.*$/'"# $_now.$_rand"'/' ~/Desktop/cache.mf
Looks like you left -e off the sed expression!
I haven't checked your sed expression itself, but the base problem is you need to identify your sed expression with the -e option:
sed -i '' -e '1 s/[\d\-\.]+/$_now.$_rand/' ~/Desktop/cache.mf
Here ya go:
_now=$(date +"%Y-%m-%d")
_rand=$RANDOM
sed -i -e "s/# [0-9]\+-[0-9]\+-[0-9]\+.[0-9]\+/\# $_now.$_rand/" ~/Desktop/cache.mf