Tag Info

Hot answers tagged

13

sed creates a temporary file, writes the output into that file, and then renames the temporary file over the top of the original. You can watch what happens using strace: $ strace -e trace=file sed -i -e '' a execve("/usr/bin/sed", ["sed", "-i", "-e", "", "a"], [/* 34 vars */]) = 0 <...trimmed...> open("a", O_RDONLY) = 3 ...


11

Backslash the +: $ echo "104_Fri" | sed 's/^\([0-9]\+\)_\([A-Za-z]\+\)$/\1;\2/' 104;Fri Note that + is not a standard basic regular expression metacharacter, and so doesn't have portable behaviour in sed even when backslashed. You should use sed -r or sed -E to enable extended regular expressions instead, in which you don't need to backslash any of these ...


10

grep will do a better job of this: grep -B 3 141.299.99.1 TESTFILE The -B 3 means to print the three lines before each match. This will print -- between each group of lines. To disable that, use --no-group-separator as well. The -B option is supported by GNU grep and most BSD versions as well (OSX, FreeBSD, OpenBSD, NetBSD), but it is technically not a ...


9

Assuming that 20000-words.txt is already in the format of one word per line, do: grep -vFf 20000-words.txt 50000-lines.txt >50000-filtered-lines.txt The -f argument to grep tells it to read patterns from a file, one pattern per line, instead of taking them as command line arguments. The -F argument to grep tells it that the patterns should be used as ...


9

How about this command? csplit logname.log /---\ LOG\ REPORT\ ---/ {*} Testing cat logname.log --- LOG REPORT --- Mary Had A Little Lamb --- LOG REPORT --- Her Fleece Was White As Snow After running the above command, the output I get is, cat xx01 --- LOG REPORT --- Mary Had A Little Lamb cat xx02 --- LOG REPORT --- Her Fleece Was White As Snow


8

With sed you can do a sliding window. sed '1N;$!N;/141.299.99.1/P;D' That does it. But beware - bash's insane behavior of expanding ! even when quoted!!! into the command string from your command history might make it go a little crazy. Prefix the command with set +H;if you find this is the case. To then re-enable it (but why???) do set -H afterward. ...


7

You must escape plus symbol +, too: $ echo "104_Fri" | sed 's/^\([0-9]\+\)_\([A-Za-z]\+\)$/\1;\2/' 104;Fri


7

You should be able to use sed -e :a -e '/\\$/N; s/\\\n//; ta' See Peter Krumins' Famous Sed One-Liners Explained, Part I, 39. Append a line to the next if it ends with a backslash "\".


6

Sed can't do arithmetic┬╣. Use awk instead. awk ' $4 == "calc" {sub(/calc( |\t)/, sprintf("%-6.2f", $3 - $2))} 1' The 1 at the end means to print everything (after any preceding transformation). Instead of the text substitution with sub, you could assign to $4, but doing so replaces inter-column space (which can be any sequence of spaces and tabs) ...


6

sed '/^[[:alpha:]]/{$!N;s/\n/ /;}' <<\DATA NAME_A 12,1 NAME_B 21,2 DATA OUTPUT NAME_A 12,1 NAME_B 21,2 That addresses lines beginning with a letter, pulls in the next if there is one, and substitutes a tab character for the newline. note that the s/\n/<tab>/ bit contains a literal tab character here, though some seds might also ...


6

Yes, that's an annoying thing about sed (see the sed FAQ about that). Since you're using GNU sed (-r is GNU specific), you can do: sed -En "0,/$1/p" (I prefer -E over -r as it's also supported by some other seds like FreeBSDs and is consistent with grep and a few other tools (and is going to be in the next issue of the POSIX/Single Unix Specification ...


6

what about: awk '{printf "%-25s %s\n",$2,$1}' file See: cat file 123 OneTwoThree 234 TwoThreeFour 345 ThreeFourFive 789 abcdefghijklmnopqrstuvwxyz 999 abcdefghijklmnopqrstuvwxyzABC Output: awk '{printf "%-25s %s\n",$2,$1}' file OneTwoThree 123 TwoThreeFour 234 ThreeFourFive 345 abcdefghijklmnopqrstuvwxyz 789 ...


6

Because you use *, meaning it matches 0 or more spaces. So zero or multiple spaces is substitued by one underscore _. Try: $ echo ' 1 2 3 ' | sed 's/[[:space:]]/_/g' _1_2_____3__ Remember that [[:space:]] also matches tab, newline, carriage return. Note BREs Matching Multiple Characters


6

How about something like awk '/--- LOG REPORT ---/ {n++;next} {print > "test"n".out"}' logname.log


5

You can save long string to bash variables, then use in sed command: string=[long1][long2] replace= [long3][long4] sed -e 's/'"$string"'/'"$replace"'/' file If you can use perl, you can break long pattern with x modifier: perl -e 's/ [long1] [long2] /[long3][long4]/x' file


5

sed 's'/\ '[long1]'\ '[long2]'\ '/'\ '[long3]'\ '[long4]'\ '/' file.txt Splitting on several lines with backslash does work if new lines are not indented. $ echo "a,b" | sed 's/\(.'\ > '\),\(.\)/\2-\1/' b-a Tested on Cygwin with GNU sed 4.2.2


5

You appear to be using GNU sed or another version with the \u extension, so you can do this: sed -e '/gr-description/{n;s/\b./\u&/g;}' < test1 This matches lines containing gr-description, and then runs everything in the {} at that point. n goes to the next line, printing the one we just matched, and then the s command replaces all characters that ...


5

You can use sed: sed -e 's/[0-9]*=/=/' < data This replaces (s) any text that is zero or more characters in the range 0-9 followed by an = sign with just the = sign.


5

Including the last line you'd do: sed -n '/word/,$p' That matches the first occurrence of word all the way until the last line and prints all matches. Not including the last line: sed '/word/,$!d;$d' ...which deletes negated matches and then deletes the last line. And to get from only the last match to the last line you have to try a little harder: ...


4

Here's an attempt to emulate grep -B3 using a sed moving window, based on this GNU sed example (but hopefully POSIX-compliant - with acknowledgement to @St├ęphaneChazelas): sed -e '1h;2,4{;H;g;}' -e '1,3d' -e '/141\.299\.99\.1/P' -e '$!N;D' file The first two expressions prime a multi-line pattern buffer and allow it to handle the edge case in which there ...


4

If your system doesn't support grep context, you can try ack-grep instead: ack -B 3 141.299.99.1 file ack is a tool like grep, optimized for programmers.


4

GNU sed is bundled with releases newer than Solaris 10. Otherwise, you can easily build it from source or retrieve it from opencsw or other freeware repositories. Solaris 10 packages are listed in this pdf: http://docs.oracle.com/cd/E19253-01/pdf/817-0545.pdf


4

You might also alternate addresses. You wind up using far fewer crazy backslashes that way. sed -n '/._./{/^[0-9]*.[A-Za-z]*$/s/_/;/p;}' sed -n '/[^0-9].*_.*[^A-Za-z]/d;/._./s/_/;/p'


4

Add the -r option ;-) for extended regexps, and the need to \ active content diminishes. $ echo "104_Fri" | sed -re 's/^([0-9]+)_([A-Za-z]+)$/\1;\2/' 104;Fri As the Q is written, (no background data) the splitting-task could be done in several other simpler ways: $ echo "104_Fri" | tr '_' ';' 104;Fri $ echo "104_Fri" | sed 's/_/;/' 104;Fri ... to ...


4

Just loop through the fields and check if they match or not: awk 'BEGIN{FS=OFS="|"} {for (i=1; i<=NF; i++) if ($i ~ "everyone") $i="this is what i want to see" print}' file See output: $ awk 'BEGIN{FS=OFS="|"} {for (i=1; i<=NF; i++) if ($i ~ "everyone") $i="this is what i want to see"; print}' file 123|abc|heloo good morning ...


4

It's normal behavior of sed. From POSIX sed documentation: Addresses in sed An address is either a decimal number that counts input lines cumulatively across files, a '$' character that addresses the last line of input, or a context address (which consists of a BRE, as described in Regular Expressions in sed , preceded and followed by a ...


4

A perl solution: $ perl -ple 's/\\\.1\\\.(7|8|9)/\\.1\\.10/' file | uniq RewiteEngine On RewriteCond %{REMOTE_ADDR} !^192\.168\.1\.10$ [NC] RewriteCond %{REMOTE_ADDR} ^192\.168\.1\.5$ [NC] </Directory> If you want edit inplace, you can try: perl -i.bak -nle 'next if $count and /!\^/;s/\\\.1\\\.(7|8|9)/\\.1\\.10/ and $count++ if ...


4

You can use grep: $ grep -vFf file2 file1 L3 pattern3 pattern L4 pattern4 -v, -F and -f are defined by POSIX grep. Note that the above will also match subpatterns. For example, if you have pattern in file2, that will match pattern1 in file1. To avoid that you can use -w (for GNU and BSD grep, maybe others): $ grep -wvFf file2 file1


4

Try this: $ sed -e 's/([^()]*)//g' Or you can use Perl: $ perl -pe 's/\(.*?\)//g'


4

You can use: sed -e "s/^\(limit\.\)[^']*/\1/" < data This matches limit. at the start of a line, followed by as many characters as possible that aren't ', and replaces it with just the part at the start (\1). You can edit the pattern and the replacement according to how your data actually is - the important part is [^']*.



Only top voted, non community-wiki answers of a minimum length are eligible