New answers tagged

1

Assuming this is part of a JSON file, the following jq command would find all objects with a trait_type key and a value key and delete all of those objects where the value key has the value None. jq 'del( .. | select( type == "object" and has("trait_type") and has("value") and .value == "None" ...


2

grep -P '\xAB' doesn't look for a hex character. There is no such thing as a hex character. \xAB is PCRE syntax to match a character whose codepoint value expressed in hexadecimal is 0xAB (171 in decimal). codepoint here would be the Unicode codepoint in locales that use UTF-8 and byte value in locales that use a single byte charset (GNU grep -P doesn't ...


1

You can include a rang instead of using a wild card to match all ASCII characters, like so: grep -Pe '\x00\x50\x53\x46[\x00-\x7F]\x01\x00\x00\x34\x01\x00\x00'


0

You could use the shell built-in read: var='XXXX YY ZZZZZ aaa,bbb,ccc' { read -r _; IFS=, read -r out _; } <<< "$var" This will result in the variable out="aaa" (can be seen with declare -p out).


3

There are two problems with your RegEx. It may be due to a misunderstanding on how RegExes work. You have used the "extended" regular expression syntax, which makes () special characters used to denote capture groups. However, they do otherwise not interfere with the matching mechanism itself. Since you don't make use of the capture group, your ...


1

Using cut: cut -d, -f1 will give you the first field (-f1) until the delimiter -d If you want the last line only, you can pipe from tail. Or pipe from sed to get a specific line. tail -n1 <<< "$var" | cut -d, -f1 sed -n 2p <<< "$var" | cut -d, -f1


1

echo "XXXX YY ZZZZZZZ aaa,bbb,ccc" | awk -F, '{print $1}' XXXX YY ZZZZZZZ aaa


0

Using sed command sed "/^USet/s/-//" filename >outputfile Suppose if you want to perform on orginal file sed -i "/^USet/s/-//" filename output USet071 USet072 USet081 USet082 awk command awk '/^USe/{sub("-","",$0);print }' filename >outfile output USet071 USet072 USet081 USet082


0

The regex can be easier to work with if you use the \v pattern prefix. With that, you don't have to escape (, {, [ and more. :%s/\vUSet(\d\d)-(\d)/USet\1\2/


3

Using sed: $ sed -n '2s/,.*//p' <<<"$var" aaa specifically if you are reading from a large file it's good to set a break point after your command proceed the second line. $ sed -n '2{s/,.*//p;q;}' infile this will quit the later processing on the input file.


-1

You've asked a question in a daunting subject. The best resource I can point you to is a PDF/video entitled, "Everything You Know About Regexes Is Wrong" by Damian Conway, former computer science professor (Monash University, Australia) and well-known Perl developer and author: https://slides.yowconference.com/yowwest2015/Conway-...


1

@AdminBee has already clarified what a word meant for grep, I'll just add how you can tell it to use other definition of word in this context. grep -w word is more or less looking for words that are neither preceded nor followed by word characters. Some grep implementations have a -P option to switch to perl-like regexps. perl has explicit look around ...


4

The -w option indeed tells grep to only look for lines that match fruit as a "word", meaning that it must either start at the beginning of the line or be preceded by a "non-word" character, and either end at the end of the line or be followed by a "non-word" character. However, a "word" character as per the man-page of ...


7

Another option using sed: sed -n 's/,.*$//p' <<< "$var" This will substitute (s/../../) everything starting from the first , on each line to the end of the line (,.*$) with "nothing", thereby leaving only the part before the first ,. By using the -n option, output is suppressed by default. The p at the end of the program ...


17

You don't want regexes there. The entire point of awk is to automatically split a line into fields, so just set the field separator to , and print the first field of the second line: $ printf '%s' "$var" | awk -F, 'NR==2{print $1}' aaa Or, if your shell supports <<<: $ awk -F, 'NR==2{print $1}' <<<"$var" aaa If you ...


2

Another way using awk could be: awk -F, '{ getline; print $1 }' <<<"$var" The field delimiter is , then getline will jump to the next line and print the first record Edge case: If var contains the following: var="foo bar baz\n aaa,bbb,ccc\n qux foo\n ddd,eee,fff" then aaa ddd would be printed.


8

Alternatively, you could also use the ${param#pattern} and ${param%%pattern} standard parameter expansion operators here: NL=' ' out=${var#*"$NL"} # removes first line. Assumes there are at least 2 out=${out%%"$NL"*} # removes all but the first line out=${out%%,*} # removes everything after the first , Or with bash specifically, you ...


6

awk -F, '/,/ {print $1}' <<< "$var" This tells awk to use a comma character as the field delimiter, and to search for any line which contains a comma. Once a line containing a comma is found, awk is told to print the first field from that line, i.e. everything up to but not including the first comma.


0

Using Raku (formerly known as Perl_6) raku -MXML -e 'for open-xml($*ARGFILES) {.elements(:TAG<ExperimentName>)>>.contents.put};' < input.xml Sample Input: <?xml version="1.0"?> <RunParameters xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <...


1

Using Raku (formerly known as Perl_6) raku -pe 's/ ^^ (.*) $$ /{print " " x (10-$0.chars); $0}/;' Sample Input: when in the course of human events Sample Output: when in the course of human events Nice coding in Perl from @Boyd led me to this answer, which is a simple way to right-justify lines. The Raku s/// operator tolerates ...


1

Using only xmlstarlet: experiment_name=$( xmlstarlet sel -t \ -m '/RunParameters/ExperimentName' \ -v 'substring-before(substring-after(., "-"), "-")' file.xml ) This matches the node that we're interested in, and then strips out the middle part of that node's value using the two functions substring-after() and ...


-1

You can also extract that name by grep (option -E allows extended regular expressions): runNumber=$(grep -Eo '[[:alnum:]]+-[[:alnum:]]+' A.xml | cut -d- -f2) If you want to ensure the line of that tag, you can pre-filter it by another grep command: runNumber=$( grep '<ExperimentName>' A.xml \ | grep -Eo '[[:alnum:]]+-[[:alnum:]]+' \ | cut -d- -...


3

Since you are processing structured data, you should use a dedicated parser such as xmlstarlet to extract the tag value for feeding to cut: xmlstarlet sel -t -c "string(/RunParameters/ExperimentName)" A.xml | cut -d- -f 2 So, you can use runNumber=$(xmlstarlet sel -t -c "string(/RunParameters/ExperimentName)" A.xml | cut -d- -f 2)


0

You could select any block from "TIMESTAMP" to "XYZ" and introduce NUL as separator after the block via sed, then sieve out via other tools, e.g. grep and remove the NUL byte in the end: tail -f file | sed -n '/TIMESTAMP/,/XYZ/{/XYZ/s/$/\x00/;p}' | grep -z 'ABC' | grep -z -v 'ZZZ' | tr -d '\x00'


0

Updated: tail -f log | sed '/\n/!N;N;/\nABC$/!D;N;N;N;N;N;N;/ZZZ/d' Displays a line that matches the ABC template, 2 preceding and 6 following if they do not have a template ZZZ There are always 3 lines in the buffer. We check the last one. If there are no matches, delete the first one and move the execution to the beginning of the script. If there is a ...


0

What you can do is determine the starting and ending pattern. For example, let's use TIMESTAMP HERE and XYZ for that purpose and use sed to find all the lines in betweeen. sed -n '/^TIMESTAMP HERE/,/^XYZ/p' logfile.txt


0

Using Raku (formerly known as Perl_6) raku -ne '.put if m:g/^^ [ [\d+ [\-\d+]?] [\,|$$] ]+ $$/;' Sample Input: 1,2,3-5,6 1,2,3-5,6, 1 1-3 1,2,3-,4,5-7 1,2,3-,4,5-7, 1,2,-3,4,5 1,2,-,3,4 1,2,,,3,4 ,1,2,3 Sample Output: 1,2,3-5,6 1,2,3-5,6, 1 1-3 An advantage of using Raku is whitespace tolerance within the matcher. This makes for more readable code. ...


2

You may use = to output the line number of a line in the editing buffer. To search with some expression RE and output the line number of the first hit, use /RE/ = The n command outputs the current line prefixed by its line number. Applying it to some other line or range of lines is also possible: /RE/ n To get the line numbers of all matching lines, ...


2

Switch from bash to zsh which does have a decimal range glob operator (it can also, contrary to bash use variables in {$start..$end}, but that's not a glob operator). #!/usr/bin/zsh - if (( $# == 3 )) && start_day=$1 end_day=$2 month=$3 && [[ $start_day = <1-31> && $end_day = <1-31> && $month = <1-12&...


3

You can use the g + n (global + number commands): $ ed -p 'ed> ' file ed> ,p tree apple lemon fruit not here pear apricot end ed> g/a/n 2 apple 7 pear 8 apricot Always check the documentation to see all commands available: POSIX Ed and GNU Ed.


-3

awk '/\$remote_addr/{for(i=1;i<=NF;i++){if($i ~ /\([0-9].*|[0-9].*\)/){print $i}}}' filename|awk -F "(" '{gsub(/\).*/,"",$2);print $2} output 1.2.3.4|5.6.7.8


0

Here, you don't need sed, though. You could just do: grep -v '[hlrw]' The first (non-standard) sed -e 's/\s/\n/g' could also be replaced with: tr -s '[:space:]' '[\n*]' which transliterates and squeezes all sequences of white spaces into a newline character. That would actually justify the use of cat (which is not needed for sed, as sed can take filenames ...


2

My version of GNU find supports a few different regex variants, which can be chosen with -regextype: valid types are ‘findutils-default’, ‘awk’, ‘egrep’, ‘ed’, ‘emacs’, ‘gnu-awk’, ‘grep’, ‘posix-awk’, ‘posix-basic’, ‘posix-egrep’, ‘posix-extended’, ‘posix-minimal-basic’, ‘sed’. Almost all of those let the dot match a newline, ...except emacs, which is the ...


-2

The command find ~user would find all names, including those containing newlines. Add -type f if you want to only find regular files. If you don't want to restrict the matching of names, don't use a test on the names. To restrict the names matched using substrings, you could use a globbing pattern with the -name test. Both * and ? matches newlines in a ...


0

You could also try this sed sed -En '/\$remote_addr/ s/.*\(([0-9.]*\|[0-9.]*)\).*/\1/p' $file It will match any line with $remote_addr then extract the match. The code should be able to match the pattern without explicitly matching $remote_addr beforehand. sed -En 's/.*\(([0-9.]*\|[0-9.]*)\).*/\1/p' $file Output 1.2.3.4|5.6.7.8


3

Since it's a simple substitution on a single line I'd just use sed for that: $ sed -n 's/.*$remote_addr[^(]*(\([^)]*\).*/\1/p' file 1.2.3.4|5.6.7.8 If you really want to use awk though, then you can do this with any awk: $ awk 'sub(/.*\$remote_addr[^(]*\(/,"") && sub(/).*/,"")' file 1.2.3.4|5.6.7.8


1

Considering you want to extract the content of the inner parentheses of the if ($remote_addr ~ ( ... ) ) statement, the following awk program should to: awk 'index($0,"$remote_addr"){sub(/^.*\(/,"");sub(/\).+$/,"");print}' inputfile This will match the line that contains the string $remote_addr. In that line, it will remove ...


1

You may use the following custom decoder to extract all fields: <decoder name="log1"> <prematch>^\d\d.\d\d.\d\d\d\d \d\d:\d\d:\d\d.\d\d\d [\d+]\s+\w+\s+\w+\s+- </prematch> <regex>^(\d\d.\d\d.\d\d\d\d \d\d:\d\d:\d\d.\d\d\d) [(\d+)]\s+(\w+)\s+(\w+)\s+-\s+(\.+):\s+(\S+),(\S+),(\S+),(\S+),(\S+),(\S+),(\S+),(\S+)</regex>...


0

This is another answer based on perl, this one uses perl -ne which feeds/consumes all lines of the input into the perl program. The perl program has an if statement containing your regex with the capture group and, when, we found a match, we print it. When we print the capture group we add a newline. The newline is essential to ensure that multiple matches ...


2

The POSIX specification for basic regular expressions do not allow \n to match a literal newline (my emphasis below): The Shell and Utilities volume of POSIX.1-2017 specifies within the individual descriptions of those standard utilities employing regular expressions whether they permit matching of <newline> characters; if not stated otherwise, the ...


2

With that input all you need is: $ tr -d '${}' < file alarm_name = "var.environment-var.deployment-var.service_name-elb-healthyhosts" If that's not all you need then edit your question to provide more truly representative sample input/output that that won't work for.


1

Your issue is that .* also matches the intermediate ${} between the initial ${ and the final }. You may use s/${\([^}]*\)}/\1/g instead, which is almost what you have except that .* is replaced with [^}]*, which matches zero or more non-} characters. The /g at the end repeats the substitution for all non-overlapping matches. This would however not work on ...


2

I'd use sed -E 's/\$\{([^}]+)\}/\1/g' Demo: $ line='alarm_name = "${var.environment}-${var.deployment}-${var.service_name}-elb-healthyhosts"' $ sed -E 's/\$\{([^}]+)\}/\1/g' <<<"$line" alarm_name = "var.environment-var.deployment-var.service_name-elb-healthyhosts"


0

Assuming that if one of the strings you're searching for doesn't appear in the input you want to see it printed with a count of 0 rather than not printed at all, the robust, portable, efficient, concise way to do this is simply: $ awk -F',' -v tgts='Want,Need' ' { cnt[$8]++ } END { split(tgts,t); for (i in t) print t[i], cnt[t[i]]+0 } ' file Want 1 ...


1

I'm assuming that you are actually using double quotes around your sed expression rather than single quotes, or you would not get that error. I'm also assuming that you are using a string in your $replace value that contains a slash (/). When the variable is expanded, its value is injected into the sed statement and since it contains a slash, it breaks the ...


Top 50 recent answers are included