Using variables with sed - linux

I'm trying to delete a part of a file using sed in Linux (Ubuntu). Specifically, I want to delete the first lines of a log file until the first occurrence of the current system date (using the pattern '10 Jan 13').
So, I store the date in a variable
root#server:/# VAR_DATE=`date -R | cut -c6-11`
And after that, I use sed
root#server:/# cat log_file.txt | sed -n -e '/$VAR_DATE/,$p'
But it doesn't work. I've tried a lot of combinations with the same result:
root#server:/# cat log_file.txt | sed -n -e '/"$VAR_DATE"/,$p'
root#server:/# cat log_file.txt | sed -n -e '/"${VAR_DATE}"/,$p'
root#server:/# cat log_file.txt | sed -n -e "/$VAR_DATE/,$p"
What I'm doing wrong?

Use double quotes so the variable $vardate gets expanded by the shell and escape the last $ so it's not expanded by the shell sed -n "/$vardate/,\$p" file:
$ cat file
6 Jan 13
7 Jan 13
8 Jan 13
9 Jan 13
10 Jan 13
11 Jan 13
12 Jan 13
13 Jan 13
$ vardate="10 Jan 13"
$ sed -n "/$vardate/,\$p" file
10 Jan 13
11 Jan 13
12 Jan 13
13 Jan 13

Related

how can i cut off the strings from an output in Bash shell?

The command i run is as follows:
rpm -qi setup | grep Install
The output of the command:
Install Date: Do 30 Jul 2020 15:55:28 CEST
I would like to edit this output further more in order to remain with just:
30 Jul 2020
And the rest of the output not to be displayed.
What best editing way in bash can i possibly simply get this end result?
Use grep -Po like so (-P = use Perl regex engine, and -o = print just the match, not the entire line):
echo '**Install Date: Do 30 Jul 2020 15:55:28 CEST**' | grep -Po '\d{1,2}\s+\w{3}\s+\d{4}'
You can also use cut like so (-d' ' = split on blanks, -f4-6 =
print fields 4 through 6):
echo '**Install Date: Do 30 Jul 2020 15:55:28 CEST**' | cut -d' ' -f4-6
Output:
30 Jul 2020
You can do it using just rpmqueryformat and bashprintf:
$ printf '%(%d %b %Y)T\n' $(rpm -q --queryformat '%{INSTALLTIME}\n' setup)
29 Apr 2020

Use Bash Perl to fetch substring off of command output

Let's presume the text I'm working with is (which is outputted by pecl install xdebug):
| - A list of all settings: https://xdebug.org/docs-settings.php |
| - A list of all functions: https://xdebug.org/docs-functions.php |
| - Profiling instructions: https://xdebug.org/docs-profiling2.php |
| - Remote debugging: https://xdebug.org/docs-debugger.php |
| |
| |
| NOTE: Please disregard the message |
| You should add "extension=xdebug.so" to php.ini |
| that is emitted by the PECL installer. This does not work for |
| Xdebug. |
| |
+----------------------------------------------------------------------+
running: find "/tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2" | xargs ls -dils
1078151 4 drwxr-xr-x 3 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2
1078337 4 drwxr-xr-x 3 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr
1078338 4 drwxr-xr-x 3 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr/local
1078339 4 drwxr-xr-x 3 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr/local/lib
1078340 4 drwxr-xr-x 3 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr/local/lib/php
1078341 4 drwxr-xr-x 3 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr/local/lib/php/extensions
1078342 4 drwxr-xr-x 2 root root 4096 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr/local/lib/php/extensions/no-debug-non-zts-20180731
1078336 2036 -rwxr-xr-x 1 root root 2084800 Feb 3 17:40 /tmp/pear/temp/pear-build-defaultuserNxuIJy/install-xdebug-2.9.2/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so
Build process completed successfully
Installing '/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so'
install ok: channel://pecl.php.net/xdebug-2.9.2
configuration option "php_ini" is not set to php.ini location
You should add "zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so" to php.ini
I want to extract this part off of this output and save it in a variable for later use:
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so
I have attempted doing it like this with Perl without success:
echo $OUTPUT | perl -lne 'm/You should add "(.*)"/; print $1'
How do I get the substring dynamically with perl? What's the pattern that I need to use?
With the $OUTPUT text placed in a file output.txt
cat output.txt | perl -wnE'say $1 if /You should add "(zend_extension=.*)"/'
This uses the specifics of the shown text, in particular the seemingly unique zend_extension=... preface for the path, to distinguish the needed line from an earlier "You should add" pattern. Change as needed, to what is more suitable for your problem.
If the text is thrown at the one-liner as one string in your code then add -0777 flag to test.
Otherwise please clarify how that $OUTPUT comes about.
Tested with a bash script
#!/bin/bash
# Last modified: 2020 Feb 03 (12:58)
OUTPUT=$(cat "output.txt")
echo $OUTPUT | perl -wnE'say $1 if /You should add "(zend_extension=.*)"/'
where output.txt is a file with the text from the question, and the right line is printed.
You can use this perl:
perl -lne 'print $1 if /You should add "(?!extension=xdebug\.so)([^"]+)"/' <<< "$OUTPUT"
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so
Negative lookahead (?!extension=xdebug\.so) will ignore line extension=xdebug.so in output.
Alternatively you may match You should add at the line start:
perl -lne 'print $1 if /^You should add "([^"]+)"/' <<< "$OUTPUT"
Probably OP meant to use
echo $OUTPUT | perl -ne 'm/You should add "(.*)"/ && print $1'
or
echo $OUTPUT | perl -ne 'print $1 if m/You should add "(.*)"/'

Linux Grouping and Counting Files by attribute

I am trying to return a list of the months that files were created using the following code.
ls -l|awk '{A[$6":"]++}END{for (i in A){print i" "A[i]}}'
I am using the below code to validate each output.
ls -la | grep -c "Jan"
However as you can see from my output:
: 1
Jan: 19
Feb: 11
Mar: 28
Apr: 10
May: 14
Jun: 24
Jul: 4
Aug: 16
Sep: 10
Oct: 30
Nov: 4
Dec: 1
Output of ls|grep
I end up with 1 record showing no date. Also both January and December are short by 1. Can anyone assist?
You could do it this way using awk and sort
$ ls -l | awk '$6!=""{m[$6]++}END{for(i in m){printf "%s : %s%s",i,m[i],ORS }}' | sort -k1M
Jan : 7
Mar : 1
Apr : 8
Aug : 2
The problem comes with the first line of ls -l which doesn't contain a month field

how can I add number lines to a file with in this script

So I have this script file that automatically saves the date and time to a file when the terminal is open. But i'm having a hard time putting number lines in it. I tried cat -n, grep -n, ls -l, but I either get errors or doesn't increment. As you can see:
My Script
echo $(date) >> .test
I would like to see something like this:
0 : Tue Feb 15 13:10 EST 2014
1 : Tue Feb 18 12:10 EST 2014
2 : Tue Feb 18 10:10 EST 2014
3 : Tue Feb 19 13:22 EST 2014
If you pipe the result into cat, you can use the -n option to number each line like so:
ls | grep "whatever" | cat -n
Here's a solution:
echo $(wc -l < filename) : $(date) >> filename
Try saving the last number in a file. Then, in your script, read in the number, increment it, and write it back to the file. If you are using bash, something like this should work.
num=$(cat number.txt)
num=$(($num+1))
echo $num > number.txt

Unusual behaviour of linux's sort command

On Linux shell the result of echo -e "arrays2 2\narrays 2\narrays3 2" | sort is
arrays 2
arrays2 2
arrays3 2
and the result of echo -e "arrays2 28\narrays 28\narrays3 28" | sort is
arrays2 28
arrays 28
arrays3 28
Why in the second case the string arrays2 28 appears on first line.
Is this a bug, or I miss something?
I tried this on RHEL4 and Ubuntu 11.04.
Thanks.
The behaviour is locale-dependent:
echo -e "arrays2 28\narrays 28\narrays3 28" | LANG=C sort
prints
arrays 28
arrays2 28
arrays3 28
While
echo -e "arrays2 28\narrays 28\narrays3 28" | LANG=de_DE.UTF-8 sort
prints
arrays2 28
arrays 28
arrays3 28
(Note that the locale must be installed for this to have this effect, if the locale doesn't exist, the behaviour will be the same as with LANG=C).
If you change the locale from en_US.utf8 to the old default, it works the way you expect:
echo -e "aaa\nfoo\narrays2 28\narrays 28\narrays3 28" | LC_ALL=C sort -
aaa
arrays 28
arrays2 28
arrays3 28
foo

Resources