Tag Info

Hot answers tagged

18

You can do it with single command with sed 's/\(.*\)-/\1 /' The point is that sed is very greedy, so matches as many characters before - as possible, including other -. $ echo 'swp-RedHat-Linux-OS-5.5.0.0-03' | sed 's/\(.*\)-/\1 /' swp-RedHat-Linux-OS-5.5.0.0 03


10

You could also handle this with bash parameter expansion: s=swp-RedHat-Linux-OS-5.5.0.0-03 echo ${s%-*} ${s##*-} Output: swp-RedHat-Linux-OS-5.5.0.0 03


8

Something like this worked for me, although I'm sure there are better ways echo "swp-RedHat-Linux-OS-5.5.0.0-03" | rev | sed 's/-/ /' | rev swp-RedHat-Linux-OS-5.5.0.0 03


5

You can use another tool that lets you set the input record separator. For example Perl perl -pe 'BEGIN{ $/="}{" } s/}{/}\n{/g' file The special variable $/ is the input record separator. Setting it to }{ defines lines as ending in }{. That way you can achieve what you want without reading the entire thing into memory. mawk or gawk awk -v RS="}{" ...


5

sed -e 's/string>!\[TEST\[\(.*\)]>\/string>/\1/' file or sed -e 's|string>!\[TEST\[\(.*\)]>/string>|\1|' file Output: Extract this string


5

If you are using GNU sed, try: sed -e '0,/claudio/ s/claudio/claudia/' nomi sed does not start checking for the regex that ends a range until after the line that starts that range. From man sed (POSIX manpage, emphasis mine): An editing command with two addresses shall select the inclusive range from the first pattern space that matches the first ...


5

To get the output you want, you could either use awk, cut or sed. The former is preferable. If your file Doc1.lst is as follow John1 0 Julien 10 Jules3 0 Julie 30 The following awk command will get the output you want. Assuming field separator is a space. awk '{print $1}' Doc1.lst Using cut cut -d' ' -f1 Doc1.lst Or using sed. Note. sed is ...


5

If the only # are the beginning of the block then with awk you can try $ awk -F'\n' 'BEGIN{RS="#"}NR>1{print "#"$1;for(i=NF-1;i>1;i--)print $i}' file Result: #Start para 3 you dq 2 welcomes dq 1 world dq 0 hello dq #Start para 2 you tq 1 are tq 0 how tq #Start para 4 world dq 3 the dq 2 to dq 1 hello dq 0 say dq


5

Use double quotes instead of single quotes. sed -i "${line_no}..." See Stack Overflow:Difference between single and double quotes in bash


5

You can use Bash's parameter expansion: string="foo-bar-123" && printf "%s\n" "${string##*-}" 123 If you want to use another process, with Awk: echo "foo-bar-123" | awk -F- '{print $NF}' Or, if you prefer Sed: echo "foo-bar-123" | sed 's/.*-//' A lighter external process, as Glenn Jackman suggests is cut: cut -d- -f3 <<< "$string" ...


4

sed -n -e '/[A-Z][A-Z][A-Z]/p' prints the lines that match that regexp. Here, you'd want: sed -n 's/.*\([[:upper:]]\{3\}\).*/\1/p' That is, you want to substitute a sequence of any characters (as many as possible) followed by 3 uppercase letters (captured in \1 with \(...\)) followed by a sequence of any characters with the captured letters and print ...


4

The [0-9]* is not useless; it matches any number (0-9) that show up before the even number range ([02468]). This is to take into account multi-digit even numbers. For e.g., if you didn't have ^[0-9]* anchored to beginning of your pattern, it would not match: 92 910 308 20 The other pattern you mentioned (/^[02468]/) would only match anything that begins ...


4

The -i/--in-place flag edits a file in place. By default, sed does the (arguably) simplest possible thing and doesn't check if the file is a symlink, before reading from it, transforming, then truncating and writing. GNU sed has a --follow-symlinks flag, which makes it behave as you want with symlinks: $ echo "cat" > pet $ ln --symbolic pet pet_link $ ...


3

awk -F'|' -v p='Field3' -v r='T' ' NR==1{ for (i=1;i<=NF;i++) if ($i==p) f=i print next} $f=r ' If you like to format it to use like script.awk save it like: #!/usr/bin/awk -f BEGIN{ OFS=FS="|"} NR==1{ for (i=1;i<=NF;i++) if ($i==p) f=i print next} $f=r ...


3

You need to tell the string not only what to match, but what to save as well: sed -ne 's@string>!\[TEST\[\([^]]*\)\]>/string>@\1@gp' The s command in sed takes two arguments: a regular expression and a replacement string. Typically, the / delimiter is used to separate the two, but you can use any character, in this case @. There are some ...


3

Here are 2 more programmatic efforts with sed: they both read the whole file into a single string, then the search will only replace the first one. sed -n ':a;N;$bb;ba;:b;s/\(claudi\)o/\1a/;p' file sed -n '1h;1!H;${g;s/\(claudi\)o/\1a/;p;}' file With commentary: sed -n ' # don't implicitly print input :a # label "a" ...


3

With zsh: setopt extendedglob # best in ~/.zshrc extract_numbers() REPLY=${(SM)REPLY##<->-<->} for file (*<->-<->*.dat(no+extract_numbers)) { do-what-you-will-with $file } We define a sorting function (extract_numbers) that returns the Substring of the file name that Matches <->-<-> (<-> matching any positive ...


3

Perl to the rescue: perl -i~ -e ' $/ = \1024; while (<>) { print "\n" if $closing and /^{/; undef $closing; s/}{/}\n{/g; print; $closing = 1 if /}$/; } ' input1 input2 Setting $/ to \1024 will read the file in chunks of 1024 bytes. ...


3

Your expression is telling sed to match either <?xml.*><Haystack or Foo. The Regex engine uses the capturing parenthesis to tell how far left or right to extend the or operator. (If you used a PCRE engine, then you could use non-capturing parenthesis.) Original, problematic code: echo "20150310 21:12:01.846338::: <?xml ...


3

Do not use regular expressions to parse XML. It's an excellent way to create brittle code, because there's a bunch of perfectly valid things you can do with XML which will break a regex. Things like reformatting the XML in entirely valid ways (such as 'pretty printing' it in a nested/indented form) will break your code. Instead I would suggest - use an XML ...


3

You say you want the date/time field quoted? awk 'BEGIN {FS=OFS=","} $2="\""$2"\""' infile > outfile


3

A very simplistic way is to replace the first and second commas as you said: sed 's/,/,"/;s/,/",/2' infile unless you want to match the date (assuming it's the same format on all lines): sed 's/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\ [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)/"&"/' infile or everything between the first and second comma: sed ...


3

Assuming the output in the question is the desired output, you can try this. awk -F';' 'BEGIN{OFS=",";} NR>1{gsub(/ /,""); print $2,$3,"DATABASES"}' filename | sed -e :a -e '$!N;s/\n/,/;ta' Probably this could be accomplished with awk only. Remove the sed part if you want lines in the same row. Since SE seems to be having educative purposes, I'll ...


3

You're looking for tail : ls -ltr | tail -n 1 This will display only the last line of ls -ltr's output. You can control the number of lines by changing the value after -n; if you omit -n 1 entirely you'll get ten lines.


2

The other answers give solutions for sed and awk. If your sed and awk don't support multibyte characters, there's still a good chance that your bash does support them, so here is a pure-bash solution. First we choose a random number between 0 and the length of the string $a, inclusive, so that the string $b can be inserted between any two characters of $a, ...


2

A few problems here: The slashes (/) within your expression must be escaped. The outermost brackets should be parentheses or be omitted altogether. If you want any amount of space allowed and replaced, the expression should be [[:space:]]*, rather than just [[:space:]]. Try this: 's/[0-9][0-9]\/[0-9][0-9]\/[0-9][0-9][0-9][0-9][[:space:]]*/h/g'


2

you almost make it awk '(NR>1) && ($8 > 2 ) ' foo > bar where NR is number of record (that is number of line) $8 is eight field && is logical and foo is the original file, unchanged bar resulting file implicit default action is to print the current input line note that header is striped from foo to bar, to keep it awk ...


2

First of all you should realise that a .tar file is normally not compressed (it would more likely have an extension .tar.gz or .tar.xz if it is). And your tar -xvf xyz.tar extracts the files and lists the names, sed works on the list of filenames, not even the file contents. If you have exact same length substitutions as the originals, then you could ...


2

You can use sed to process tbd.txt and create a sed script from it which would delete the lines. Something like sed 's=^=/=;s=$=/d=' tbd.txt | sed - file.csv


2

A simple approach with Awk: awk -F'[][]' '{print $3}' file



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