LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 04-23-2009, 04:11 PM   #1
unim21
LQ Newbie
 
Registered: Apr 2009
Posts: 11

Rep: Reputation: 0
Using "index" to grab a value from a file name?


Okay, lets say i do this in a script.


for x in `ls test.* -a1t | head -1`; do
done

This will store the first listing of the LS command into variable X.

Now, lets say the listing is called test.001-006.whatever

How do I use "index" to find what number is after the dash?

I've tried char *index(const char *$x, int 3);

It doesn't seem to work.
 
Old 04-23-2009, 04:32 PM   #2
rweaver
Senior Member
 
Registered: Dec 2008
Location: Louisville, OH
Distribution: Debian, CentOS, Slackware, RHEL, Gentoo
Posts: 1,833

Rep: Reputation: 164Reputation: 164
Quote:
Originally Posted by unim21 View Post
Okay, lets say i do this in a script.


for x in `ls test.* -a1t | head -1`; do
done

This will store the first listing of the LS command into variable X.

Now, lets say the listing is called test.001-006.whatever

How do I use "index" to find what number is after the dash?

I've tried char *index(const char *$x, int 3);

It doesn't seem to work.
Are you programming in C or SH? You can't mix languages. Shell doesn't use type. What are you trying to do exactly? That 'head -1' means you're only going to run the loop once and you're going to store . as the variable.

Run the command at the prompt to see what you're dealing with before you do it. You also don't need -1 as an argument to ls when using it that way.

I think what you're wanting to do is this based on what you've provided so far. It sets y to the value after the dash in the example you gave. There are far better ways but this is quick and dirty and gets it done.

Code:
for x in `ls test*`; do 
 y=`echo $x|cut -f2 -d'.'|cut -f2 -d'-'`; 
 y++;
done
EDIT:
I suppose I should explain that a bit:

args to cut are -f (field) #2 -d (delimiter) .
args to second cut are -f (field) #2 -d (delimiter) -

so in the example you gave:

test.001-006.whatever

echo $x = test.001-006.whatever
cut -f2 -d'.' on test.001-006.whatever = 001-006
cut -f2 -d'-' on 001-006 = 006

You could do the same thing with sed, awk, perl, or any number of tools. If you've got a fair amount of shell scripting to do I would suggest you look up a tutorial on basic bash scripting.

EDIT2: You should look into using logrotate.

Last edited by rweaver; 04-23-2009 at 04:56 PM. Reason: explaining, logrotate.
 
Old 04-23-2009, 04:32 PM   #3
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 23,066
Blog Entries: 11

Rep: Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910Reputation: 910
Ummm ... what are you doing in which language?

Are you invoking a shell-script from a C-program?
 
Old 04-23-2009, 04:35 PM   #4
unim21
LQ Newbie
 
Registered: Apr 2009
Posts: 11

Original Poster
Rep: Reputation: 0
Here's what I am trying to do.

We're making backups of MySQL transaction log files.

My script has to first mount to a file server and look to see if there is a file called something.000-003.tar.gz

If the file is there, the script says "Okay, now i'm going to look where the binlogs are, and based on the second number in that file I'm going to start with the number after that when compressing the new log files.

So, if the script finds a file called something.001-034.tar.gz, it needs to compress the log files starting with .035 to whatever I specify.

This is all in shell.

Last edited by unim21; 04-23-2009 at 04:40 PM.
 
Old 04-23-2009, 05:04 PM   #5
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
If you retrieve a single file name from the ls + head commands, you don't need a for loop: just store the filename in the variable "index". Then you can remove the unwanted parts from the string using parameter substitution and finally increase the value by 1 padding it with leading zeros:
Code:
index=$(ls -t test.* | head -1)
index=${index##*-}
index=${index%%.*}
index=$(printf '%03d' $(expr $index + 1))
 
Old 04-23-2009, 05:57 PM   #6
unim21
LQ Newbie
 
Registered: Apr 2009
Posts: 11

Original Poster
Rep: Reputation: 0
Okay, so this is what I have so far.

Under the directory /root/test/gzfiles there are 2 files.

'test.000-004.tar.gz'
'test.005-009.tar.gz'

I then run this script...

for x in `ls /root/test/gzfiles*`; do
y=`echo $x|cut -f2 -d'.'|cut -f2 -d'-'`;
if [ $y -ne 005 ]; then
echo $y
else
echo $y
fi
done


This returns the values 004 and 009 back into my console.

What I need to be able to do is take the value 009, and tell the script to tar.gz all after 009 (i.e., 010 011 012 013 etc.)

Thanks in advance
 
Old 04-23-2009, 06:35 PM   #7
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Once you have extracted the last number, just create a tar archive then loop until the number of the last file is reached and append every file to the archive. Finally rename the archive using the first number and the last one:
Code:
#!/bin/bash
# extract the last number from the last archive name
num=$(ls -t *.tar.gz | head -1)
num=${num##*-}
num=${num%%.*}
# increase the number by one preserving the three digits format
num=$(printf '%03d' $(expr $num + 1))
# store the number to rename the new archive
from=$index
# create the archive adding the first file
tar cf tmp.tar $index
# loop until the exit code of the tar command is 0 (successful)
while [ $? -eq 0 ]
do
  # increase the number by one and append the new file to the archive
  num=$(printf "%03d" $(expr $num + 1))
  tar rf tmp.tar $num 2> /dev/null
done
# compute the number of the last added file
to=$(printf "%03d" $(expr $num - 1))
# rename the archive and gzip
mv tmp.tar test.${from}-${to}.tar
gzip test.${from}-${to}.tar
Just put the real filenames and the correct paths (in my example I assume all the files are in the current directory and the files added to the archive are called simply 010 011 012 013 and so on).
 
Old 04-24-2009, 09:04 AM   #8
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 7,151

Rep: Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203Reputation: 2203
#DEFINE FLAME ON

I hate to see code that's done like this, just because I wind up having to maintain it!

As the Perl community likes to say, "TMTOWTDI = There's More Than One Way To Do It." Therefore, since you have so many programming-environments to choose from in Linux, try to choose the best way. That is, the one that:
  • ... describes the essential problem that is to be solved in the most general way
  • ... is obvious to your colleagues and successors
  • ... is the most maintainable.
Think about it: if you devise a solution that uses substrings to parse a filename like, say, backup_file.336.txt, everything might work just fine until, one day, months later, the one-thousandth backup file is created. The original solution, which certainly "worked" for 999 files, abruptly parses "1000" as either "100" or "000" and breaks.

Maybe it "crashes and burns," but more likely, it will fail silently, perhaps writing-over important files.

Now, under great pressure and in a tremendous rush, your successor/colleague, "the maintainer," is desperately trying to find the bug. First s/he must locate the file in question, then s/he must understand what it is doing. Then, s/he must somehow fix it. Will s/he be happy, or will s/he be muttering epithets about your ancestry?

"A shell script" is not the right tool for this job. Since you have so many general-purpose programming languages at your beck and call, all of them just a #!shebang away, you should use one of them.

In the Perl community, for instance, a regular expression would quite-instinctively be used to solve this problem, because it is a general-purpose solution. The regex /^backup_file\.([0-9]+)\.txt$/ will match all such files of this format and will extract "sequence of one-or-more digits" from the middle of it. It's reasonably obvious (with just a little practice) to "see" what the pattern is supposed to be doing, and it expresses a generalized solution to the problem. This makes a huge difference in maintainability.

When you write software, "write it to last two dozen years," because it probably will (even if you don't).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how can I "cat" or "grep" a file to ignore lines starting with "#" ??? callagga Linux - Newbie 7 08-16-2013 07:58 AM
Keep getting "Could not grab your mouse" error messag jacatone Linux - Newbie 14 07-29-2011 02:55 PM
KMail Disaster - "index file" problems Riddick Linux - Software 0 11-30-2004 04:24 PM
port 80 displays "Index of" and file table rioguia Linux - Networking 9 09-25-2002 11:52 AM


All times are GMT -5. The time now is 04:55 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration