Tag Info

New answers tagged

0

#!/bin/sh ascend() { echo $( i=0 while test $# -gt 0; do i=$(($1 > i ? $1 : i + 1)) echo $i shift done ) } ascend 2 7 8 9 11 15 34 91 91 92 94 ascend 1 1 1 1 1 1 1 1 1 1 Output: 2 7 8 9 11 15 34 91 92 93 94 1 2 3 4 5 ...


0

set /^\#aliases/ /^\#end\ aliases/ sed -ne"$1,$2"'s/\\\{0,1\}/&&/gp' <stuff_to_place...rc | sed -e"$1,$2c\" -f- ./infile >./outfile If you want to edit the file in-place ed is a very good solution. If you want to edit it in-stream, use sed. Avoid sed -i.


6

Ed is the standard editor, because you can use it to develop ed scripts and let it do its work, as you tested before, interactively. For small files like .bashrc or any code text, ed is performant because it reads the whole file in one rush and works with the buffer. For the same reason you should not use ed for big files like log files. But with an ed ...


0

Your sed patterns are not anchored on the end so they match the new lines. Another solution is to modify the lines instead of deleting and readding. First let's see if we can make the original script a little more readable by not being so wide: sed -i -r '/deb http\:\/\/httpredir\.debian\.org\/debian jessie main/d' /etc/apt/sources.list sed -i -r '/deb ...


1

Your expression returns 0 because it matches the first number. Anchor the regexp to make it do what you want: [[ "1234+5678" =~ ^[0-9]+( *(-|\*) *[0-9]+)*$ ]] && echo $? On a side note: (1) you don't need to quote -, and (2) \s is not recognized as an ERE.


3

Without markers the regexp (right part) can match any part of string. So your variant match 1234. To satisfy requirements you have to use markers: [[ "1234+5678" =~ ^[0-9]+(\s*(\-|\*)\s*[0-9]+)*$ ]] ; echo $? And shorter (if you'd like): [[ "1234+5678" =~ ^[0-9\ *-]+*$ ]] ; echo $?


0

[[ "1234+5678" =~ [0-9]+(\s*(\-|\*)\s*[0-9]+) ]] ; echo $? The * regex operator at the end of your regex allows any number of repeats of the expression inside the () also none. So you match [0-9]+ from the start and the rest is optional. If you remove the * or replace it by a + the expression returns as expected. Also, the asterisk following the ...


2

I like to directly use proc for that grep -l '1[0-9][0-9]\|200' /proc/[1-9]*/comm|awk -F '/' '{print $3}' For the pid variant grep -l 'xclock' /proc/{1[0-9][0-9],200}/comm 2>/dev/null|awk -F '/' '{print $3}'


1

Using a grep version which supports PCREs (like e.g. GNU grep), to list all the matches: hostname="database.example.com.au" < inputfile grep -Po "$hostname\)\(Port = \K[0-9]+" To list only the first match: hostname="database.example.com.au" < inputfile grep -Po -m1 "$hostname\)\(Port = \K[0-9]+" Using sed, to list all the matches: < inputfile ...


1

I've never seen a formal description of tnsnames.ora, so I'm kind of guessing at the format. Here's my stab at a script to do what you want: #!/bin/bash HOST=$1 tr '()' '\n\n' < input | awk 'BEGIN {host=""; port=""} /[Hh][Oo][Ss][Tt]/ {host=$3} /[Pp][Oo][Rr][Tt]/ {port=$3} host && port { if (host == "'$HOST'") {print host, ...


2

The default regex type for GNU find is emacs, which doesn't support intervals. You can specify different regex types, such as posix-egrep, which will solve your issue: find . -maxdepth 1 -type d -regextype posix-egrep -regex './[0-9]{6}'


0

If your grep supports PCRE (Perl-compatible regular expressions) : $ grep -Po '.*/\Kfoo[^/]*$' file.txt foobar foo .*/ will match upto the last / and \K will discard the match foo[^/]*$ will find the filenames starting with foo


1

If foo must match at the start of the basename: < inputfile grep '/foo[^/]*$' /foo[^/]*$: matches a /foo string followed by any number of any character not / at the end of the string if foo can match anywhere in the basename: < inputfile grep 'foo[^/]*$' foo[^/]*$: matches a foo string followed by any number of any character not / at the end ...


0

awk '/^dn:/ {d=1} {if (d) {print buf | "sort|uniq -d"; d=0; buf=""} else {buf=buf$0"\n"}} END {print buf | "sort|uniq -d"}'|grep -v '^$' Much less typing than in perl version =). Might be even simpler, but I seems no way how to execute awk rule 'on any pattern OR at the END', so it contains little bit shell code duplication.


0

If you're interested in knowing "Are there duplicates?" then I recommend comparing the results of cat <file> | sort | wc -l and cat <file> | sort | uniq | wc -l. If there are duplicates, the uniq will remove them and the number will decrease. If you want to see those differences, look at the perl script @Igeorget posted.


0

The type of quick'n'dirty scripts I write every day: #!/usr/bin/perl # use strict; use warnings; #data structures we're gonna need my %positions; #how many times have we seen a given position my %registered_lines; #the concatenated lines for the given position my $dn; # the current dn section we're in while (<>) { if (/^dn:/) #beginning of a ...


3

This matches ( and ) literally. () is used as capturing groups in Extended Regular Expressions (as used by r's grep() or the grep command with the -E option) or Perl Compatible Regular Expression which extend Extended Regular Expressions (as used by r's grep(..., perl=TRUE) or some grep commands with the -P option). Hence to match () literally, \ is used.


1

I would first extract candidates, then check for the maximum 777 later: egrep '^[0-7]?[0-9][0-9]?)' file | sed 's/^\([0-7]\?[0-9][0-9]\?\))/\1 )/' | awk '($1 < 778) {print $0}' | sed 's/^\([0-7]\?[0-9][0-9]\?\) ).*/\1,/' | tr --delete \\n | sed 's/,$/\n/' It works for my test files. (EDIT1: The last sed now gives the number only EDIT 2: removed ...


1

As some clarification iterations showed, only integer numbers and with values not larger than 777 shall be collected into a comma separated list. Here we go: awk -F ')' '$1~/^[0-9]+$/ && $1<=777 {print $1}' <datafile | paste -sd, Note: To match an integer range you can in awk also write: awk -F ')' '$1>=1 && $1<=777 {print ...


0

There are multiple types of regular expressions and the set of special characters depend on the particular type. Some of them are described below. In all the cases special characters are escaped by backslash \. E.g. to match [ you write \[ instead. Alternatively the characters (except ^) could be escaped by enclosing them between square brackets one by one ...


3

The most reliable way to test whether a crontab line is valid is to ask the crontab utility. Most crontab utilities don't have an option to only validate and not change the crontab. You can call crontab -e to set the crontab, and if this succeeds restore the previous content, but this is not robust: if the input is valid, a job that it contains could be ...


1

With POSIX BREs that have no alternation operator, you can use that \{0,1\} instead: LC_ALL=C grep '^\.\{0,2\}\(.*[^k]\)\{0,1\}\(.*[^a].\)\{0,1\}\(.*[^b]..\)\{0,1\}$'


3

Regular languages (i.e. "this can be matched with a RE") are closed under complement, so it's possible, but it's not very useful for practical purposes: what you start out with is the condition last letter is k AND letter before that is a AND letter before that is b (let me write s[-1]=='k' and s[-2]=='a' and s[-3]=='b' in a pythonesque fashion) so a ...


4

If you use ksh (or bash with extended globbing activated, or zsh with ksh globs enabled) you can achieve the desired function using only file globbing patterns: ls -d -- !(*bak) With grep, to get a simple solution, just use the negation -v: ls | grep -v 'bak$'


3

Using find: find . -maxdepth 1 -type f ! -name "*bak" .: asserts to search in the current working directory -maxdepth 1: asserts to search only one level below the specified directory (i.e. only the current working directory) -type f: asserts to search only for files ! -name "*bak": asserts to search only for filenames not ending in bak However, if you ...


5

Using GNU grep built with recent PCRE support: echo 'st Hello world! et' | grep -oP "st\K.*?(?=et)" The key here is to use the look-ahead and look-behind zero-length assertions. \K ==> Look-behind assertion (?=et) ==> Look-ahead assertion For more info, you could read here.


4

You may want to use sed: sed -n 's/.*st\(.*\)et.*/\1/p'


2

Janis is right that you're wanting to match regex meta characters, so will need to escape them, What's been missed though is that you're in the R environment. In that case, you need fixed: grep(pattern = "c++", x = df[trow, "modeling"], fixed=TRUE) You do realize that there's help available. Try these: ?grep ?regexp


1

If you want to grep for fixed strings use fgrep or grep -F instead. If you want to use grep the meta-characters like + needs to be escaped; there are various possibilities for that, e.g. c[+][+].


1

Try this: BATCH=AB1234 awk -v batch="#Batch Job.*${BATCH}" '($0 ~ batch),/#--.*/' filename


1

sed -e 1,/^$/c\\ -e '' <infile >outfile ...would also work. As opposed to 1,/^$/d the c\<EOF> command doesn't delete the address range, exactly, but rather changes the whole block to a single string. And so this will not remove the first blank line from output - because it changes the whole first occurring text block in input (as delimited by ...


1

What you need is called the back-references. It means "put here whatever was selected in the match" and functions by: Using parenthesis in the matching regex to select a part of the string, Using a numbered back-reference (\1 for the first parenthesis, \2 for the second one, etc.). sed support this and this produces the following command (sed requires ...


0

Using sed this can done like this: echo ":;XXXXXX" | sed -re "s/\:\;X+$/&\;\;\;/g" As you are taking the data from some file, you can directly edit it inside file using: sed -ri "s/\:\;X+$/&\;\;\;/g" file.txt


1

With a recent ksh (you need ksh93s or above), you could do: cat <example.txt <#""


1

With sed: sed -n '/^$/,$p' file or: sed -e '/^$/,$!d' file With awk: awk '/^$/{p++};p' file


1

You can do sed -n '/^$/{:l; p; n; b l}' file The -n suppresses normal output. When you reach the first blank line, which is matched with the pattern /^$/, it starts a loop that prints all subsequent lines.


2

It works also for Cyrillic \v\k A bit more complicated and fails with Cyrillic \v(\c[0-9a-z_[=a=][=c=][=e=][=i=][=l=][=n=][=o=][=r=][=s=][=t=][=u=][=y=][=z=]]) Doc. Tested on Vim 7.4.


0

With the conditions: I cannot use any XML parser tool as I don't have permission , read only My xmllint version does not support xpath, and I cannot update it , read only I dont have xmlstarlet and cannot install it I resorted to finding other unconventional solutions. This awk command got me what I needed awk ' /<service.*name=/ { f=1 ; m=0 ; ...


0

If you are using the latest ksh - by which I mean a recent build of ksh93 - you can actually just use it. ksh93 supports compound variable types - which are a little like a C struct - or an XML node-tree. It doesn't natively support XML at the moment - though I believe that it is planned - but it does support json right now. I used some free online ...


0

OK, first and foremost - don't use grep. XML is not a suitable format for regex based parsing. Use an XML parser instead. My favourite XML Parser is actually a perl module called XML::Twig. #!/usr/bin/perl use strict; use warnings; use XML::Twig; my ($keyword, $filename) = @ARGV; XML::Twig->new( 'pretty_print' => 'indented_a', ...


0

Assuming a sample xml file like this: <services> <service name="GETME" min="1" max="10" idleTime="300" backend="ABC"> <handlerContainer className="com.abc.xyz.wqere.abcqwere"> <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/> </handlerContainer> ...


2

I would suggest taking a slightly different approach - parse the timestamp, then spit out a formatted timestamp. And I'd use perl for this: #!/usr/bin/perl use strict; use warnings; use Time::Piece; my $input_format = '%m/%d/%Y,%H:%M'; my $output_format = '%Y-%m-%d %H:%M:%S'; while (<>) { my ( $date, $time, @stuff ) = split(","); my ...


3

sed 'y|/|-| s/,*\(.....\)-*\([^,]*\)/\2-\1/ s// \1:00/2 ' <infile OUTPUT: 1998-01-02 09:30:00,0.4571,0.4613,0.4529,0.4592,6042175 1998-01-02 09:45:00,0.4592,0.4613,0.4529,0.4571,9956023 1998-01-02 10:00:00,0.4571,0.4613,0.455,0.4613,8939555 1998-01-02 10:15:00,0.4613,0.4697,0.4571,0.4697,12823627 1998-01-02 ...


2

And possible awk solution: awk 'BEGIN { FS = OFS = ","; } { split($1, d, "/"); $2 = d[3] "-" d[1] "-" d[2] " " $2 ":00"; $1 = ""; } { for (i = 2; i < NF; i++) printf("%s", $i OFS); printf("%s", $NF ORS);}' file


1

Use this: sed -n 's_^\([^/]*\)/\([^\]*\)/\([^,]*\),\([^:]*\):\([^,]*\)_\3-\1-\2 \4:\5:00_p' file.txt


5

sed -e 's/\(..\)\/\(..\)\/\(....\),\(.....\),\(.*\)/\3-\1-\2 \4:00,\5/' Edited to include the input from the comments below: sed -e 's#\(..\).\(..\).\(....\),\(.....\),#\3-\1-\2 \4:00,#'


3

That worked for me: sed -r 's/([0-9]{2})\/([0-9]{2})\/([0-9]{4}),([0-9:]{5})/\3-\1-\2 \4:00/g' Match 2 digits (([0-9]{2})), slash, 2 digits (([0-9]{2})), slash, 4 digits (([0-9]{4})), and then digits and : (([0-9:]{5})). Replace it with the order you wish: \3-\1-\2 \4:00 (year-month-day hour:minute:00).


0

From the (broken) code snippet you posted, you seem to want to replace the newline as well. In that case, regex anchoring by itself can't help you. The following is a solution: sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file Broken down: /[a-zA-Z]\+$/{} means apply whatever comes inside the curlies to lines that match the regex. The ...


2

Regular expressions can be anchored at the end of the line using $ (or at the beginning, using ^). If you want to replace anything matching the pattern [A-Za-z]* at the end of the line with something, then anchoring the pattern like this: [A-Za-z]*$ ...will force it to match at the end of the line and nowhere else. However, since [A-Za-z]*$ also matches ...


1

sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt Or, the long complex unnecessary way: I've found out, this can be done, still using sed, with the help of tr. You can assign another character to represent the end of the line. Another temporary character has to be used, in this case "`". Let's use "~" to represent the end of the line: tr ...



Top 50 recent answers are included