LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (http://www.linuxquestions.org/questions/linux-general-1/)
-   -   What is wrong with the "sed"? (http://www.linuxquestions.org/questions/linux-general-1/what-is-wrong-with-the-sed-810792/)

dynaguy 05-28-2010 04:28 PM

What is wrong with the "sed"?
 
Hello, all,

I have a backup script running as a cronjob. The script check the used disk space before start to backup. The command it use is
Code:

df /daily | tail -1 | sed -e 's/^[^ ]* *[0-9]* \([0-9]*\).*$/\1/'
I verified this in terminal and here is the result:
Code:

sysadmin@beta:~$ df /daily
Filesystem          1K-blocks      Used Available Use% Mounted on
/dev/sdc1            969066524 852215832  68012564  93% /daily
sysadmin@beta:~$ df /daily | tail -1 | sed -e 's/^[^ ]* *[0-9]* \([0-9]*\).*$/\1/'
852215832

Now I try to use same script on a different server. But it can't get the used space number any more. The out put is like this on the 2nd server:
Code:

sysadmin@delta:~$ df /emdata
Filesystem          1K-blocks      Used Available Use% Mounted on
/dev/sdb1            721078300  77859612 606589960  12% /emdata
sysadmin@delta:~$ df /emdata | tail -1 | sed -e 's/^[^ ]* *[0-9]* \([0-9]*\).*$/\1/'

Here I just got a blank out put.

I think it is the sed command cause the problem but I can't figure it out what is wrong with it. Can someone help me please?

druuna 05-28-2010 04:41 PM

Hi,

Why use sed:

df /emdata | awk '/\/emdata/ { print $3 }'

Hope this helps.

colucix 05-28-2010 04:55 PM

I second druuna's advice. Anyway, the reason why the sed regexp does not work in the second example is that you missed an asterisk:
Code:

sed -e 's/^[^ ]* *[0-9]*_\([0-9]*\).*$/\1/'
the space underlined in red matches only a single space between the first and the second number. This is true in your first example, false in the second one where there are two spaces. In any case the awk solution is far easier and readable.

syg00 05-28-2010 06:50 PM

sed rarely causes problems - now, regex on the other hand ... :eek:
IMHO relying on specific whitespace is very poor programming practice - as shown, awk avoids the issue here.

GazL 05-28-2010 07:28 PM

Always use df -P in scripts.

Here's an example of what can happen if you don't:
Code:

gazl@nix:~$ df
Filesystem          1K-blocks      Used Available Use% Mounted on
/dev/rootvg/lvroot      516040    429644    60184  88% /
/dev/sda1              4047904    44852  3797424  2% /boot
/dev/mapper/rootvg-lvusr
                      16513960  6660584  9014516  43% /usr
/dev/mapper/rootvg-lvopt
                        516040    16780    473048  4% /opt

As you can see, some lines are split into two, which is probably the reason you're getting a blank line.

df -P will give you one line per filesystem no matter what:
Code:

gazl@nix:~$ df -P
Filesystem        1024-blocks      Used Available Capacity Mounted on
/dev/rootvg/lvroot      516040    429644    60184      88% /
/dev/sda1              4047904    44852  3797424      2% /boot
/dev/mapper/rootvg-lvusr  16513960  6660584  9014516      43% /usr
/dev/mapper/rootvg-lvopt    516040    16780    473048      4% /opt


dynaguy 05-31-2010 04:58 PM

Thanks for all your help.

I now just use awk instead. Like this:
Code:

df /emdata | tail -1 | awk '{print $3}'

GazL 05-31-2010 06:50 PM

Quote:

Originally Posted by dynaguy (Post 3987793)
Thanks for all your help.

I now just use awk instead. Like this:
Code:

df /emdata | tail -1 | awk '{print $3}'

When I advised using 'df -P' it wasn't just idle fancy. Look what would happen if you tried that code on my box:
Code:

gazl@nix:~$ df /boot /usr 
Filesystem          1K-blocks      Used Available Use% Mounted on
/dev/sda1              4047904    44852  3797424  2% /boot
/dev/mapper/rootvg-lvusr
                      16513960  6660584  9014516  43% /usr

gazl@nix:~$ df /boot | tail -1 | awk '{ print $3 }'   
44852

gazl@nix:~$ df /usr | tail -1 | awk '{ print $3 }'
9014516

See what happened? It's quite possible your script will read the wrong value under certain circumstances.

And now, the correct way:
Code:

gazl@nix:~$ df -P /boot | tail -1 | awk '{ print $3 }'
44852

gazl@nix:~$ df -P /usr | tail -1 | awk '{ print $3 }'
6660584



All times are GMT -5. The time now is 02:34 AM.