A few things:
The first is: any command involving sed .... | sed ...
is (99.99999% of the times) wrong: sed
is perfectly capable of handling several commands in a script with loops, branches and everything a programming language offers. Use that instead of pipes.
Second: you don't need sed
at all for this. You can do this with shell-internal variable manipulation. Notice that calling a program is "expensive" in terms of time and resources: the OS needs to load the program, start a sub-process, and so on. Variable manipulation happens within the shell and foregoes all this. The worst thing one sees all the time is:
while read LINE ; do
echo "$LINE" | sed '.....'
....
done
If your file is long and you replace the sed
with variable manipulation it might be ten more lines to write but it will run in 1% of the time.
Parameter expansion (this is the "official" name for the mechanism) works like this:
echo ${variable}
This you already know: ${variable}
produces the content unaltered.
echo ${variable%pattern} ; echo ${variable%%pattern}
This cuts off <pattern> from the end of the variables contents. This is basically the same as sed "s/.txt$//"
. Try it out:
$ myfile="abc_d123_4567.txt"
$ echo ${myfile%.txt}
abc_d123_4567
You may wonder what the difference between ${variable%pattern}
and ${variable%%pattern}
is: it is "longest match" ("%%") and "shortest match" ("%"). Suppose we want to cut off not only ".txt" but any extension. We could do so by:
$ myfile="abc_d123_4567.txt"
$ echo ${myfile%.*}
abc_d123_4567
But a filename could contain several dots like this, then there would be a difference between longest and shortest match:
myfile="abc.d123.4567.txt"
$ echo ${myfile%.*}
abc.d123.4567
$ echo ${myfile%%.*}
abc
Notice that all these manipuations do NOT change the value of the variable! They just change what is displayed. If you want the effect to be lasting you would have to do:
myfile="abc.d123.4567.txt"
$ myfile=${myfile%.*}
echo ${myfile}
abc_d123_4567
There is another expansion which cuts off not from the end but from the beginning of a string: ${variable#pattern}
and ${variable##pattern}
. It works the same way as the "%" otherwise. For instance, you often need to split a pathname ("/some/path/to/a/file.name") into the path and the filename:
myfile="/some/path/to/a/file.name"
$ echo "The filename is: ${myfile##*/}"
The filename is: file.name
echo "The path to the file is: ${myfile%/*}"
The path to the file is: /some/path/to/a
There are even more of these expansions which can selectively change patterns within a string, conditionally assign values to variables and more. I hope to have piqued your interest. You are probably eager now to try this to solve your problem yourself.
I hope this helps.
bakunin