[SLE] Fw: [SLE] Shell Programing
----- Original Message ----- From: Patrick K Moorman <khadji@pld.com> To: Stefan Troeger <stefan.troeger@wirtschaft.tu-chemnitz.de> Sent: Tuesday, December 28, 1999 12:30 AM Subject: Re: [SLE] Shell Programing
I finally got to the Linbox and when I run the script I get an error:
sed: -e expression #1, char14: Unmatched ( or \(
so I try " ... | sed 's#.*\(\\)\#\1#g' added a " \ " after " ) " then I get this error:
sed: -e expression #1, char15: Unterminated 's' command
at this point I have exhasted my knowledge and the man, info, --help for sed doesn't help.
----- Original Message ----- From: Stefan Troeger <stefan.troeger@wirtschaft.tu-chemnitz.de> To: suse-linux-e <suse-linux-e@suse.com> Sent: Monday, December 27, 1999 6:35 PM Subject: Re: [SLE] Shell Programing
Hi,
On Mon, Dec 27, 1999 at 15:30 -0600, khadji@pld.com wrote:
I have a directory, say c:\top, that has sub directories c:\top\001, c:\top\002, etc. I want to run a script from c:\top (mounted as /smb on Linbox) that will go through the subdirectories renaming each file starting with 000001. I have the script written except that it starts with 1 and goes up. I also need the files to retain their extensions so I had forseen something to read the file name, slice the ext off and then reattach it, ie. abcdef.txt=>000001.txt. I am attaching what I have so far. I am making this up as I go with one eye on 'Beginning Linux Programing' from Wrox Press. Thanks for the help. [...] #! /bin/bash
x=000001
for directories in * do if -d $directories
This should be
if [ -d "$directories" ]
then for files in $directories/* do if -f $files
if [ -f "$files" ]
then mv $files $x
Enclose the variable names in double quotes. Otherwise your script will fail on filenames with spaces:
[sttr]/var/tmp/1> touch "a b" [sttr]/var/tmp/1> ls a b [sttr]/var/tmp/1> for x in *; do mv $x foo; done mv: when moving multiple files, last argument must be a directory [sttr]/var/tmp/1> ls a b [sttr]/var/tmp/1> for x in *; do mv "$x" foo; done [sttr]/var/tmp/1> ls foo
x=$(($x+1)) fi done fi done
Hmm. One problem with your script is that it won't descend into all subdirectories. If you had a directory c:\top\001\001, it would never be visited. To remedy this I'd use find to create a list of all files in the current directory and its subdirectories.
#!/bin/sh i=1 for x in $(find . -type f); do mv "$x" "$(dirname $x)/$(printf "%06d" $i)$(echo $x |sed 's#.*\(\.\)#\1#g')" i=$((i+1)) done
should do it. The mv line may look a little tricky but it really isn't. Suppose $x contained ./top/001/abcdef.txt and $i was 5. Then
dirname $x
would give you the directory name ./top/001.
printf "%06d" $i
would output 000005.
echo $x |sed 's#.*\(\.\)#\1#g'
gives you the extenstion .txt. Finally everything is concatenated to
./top/001/000005.txt
Ciao, Stefan
-- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
-- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
Hi,
On Tue, Dec 28, 1999 at 00:43 -0600, Patrick K Moorman wrote:
sed: -e expression #1, char14: Unmatched ( or \(
so I try " ... | sed 's#.*\(\\)\#\1#g' added a " \ " after " ) " ^There's a dot missing. It should read sed 's#.*\(\.\)#\1#g'
Ciao, Stefan -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
Stefan Troeger wrote:
Hi,
On Tue, Dec 28, 1999 at 00:43 -0600, Patrick K Moorman wrote:
sed: -e expression #1, char14: Unmatched ( or \(
so I try " ... | sed 's#.*\(\\)\#\1#g' added a " \ " after " ) " ^There's a dot missing. It should read sed 's#.*\(\.\)#\1#g'
Ciao, Stefan
In one and the same message both the power of the command line and the reason why a GUI interface was invented are aptly demonstrated. ;-) JLK -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
Stefan Troeger wrote:
Hi,
On Tue, Dec 28, 1999 at 00:43 -0600, Patrick K Moorman wrote:
sed: -e expression #1, char14: Unmatched ( or \(
so I try " ... | sed 's#.*\(\\)\#\1#g' added a " \ " after " ) " ^There's a dot missing. It should read sed 's#.*\(\.\)#\1#g'
Ciao, Stefan
Could someone translate this to English? I've used sed a little bit, but this intrigues me. So I checked man: s/regexp/replacement/ Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the spe cial character & to refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp. So if the script begins with "s", then a slash must follow, right? Thanks. -- George Toft http://www.georgetoft.com -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
Hi, On Tue, Dec 28, 1999 at 06:23 -1000, George Toft wrote:
Stefan Troeger wrote:
so I try " ... | sed 's#.*\(\\)\#\1#g' added a " \ " after " ) " ^There's a dot missing. It should read sed 's#.*\(\.\)#\1#g'
Ciao, Stefan
Could someone translate this to English? I've used sed a little bit, but this intrigues me. So I checked man:
s/regexp/replacement/ Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the spe cial character & to refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.
So if the script begins with "s", then a slash must follow, right?
Actually you can use any character instead of a slash here. echo foo |sed 's/foo/bar/' echo foo |sed 's@foo@bar@' echo foo |sed 's.foo.bar.' echo foo |sed 's|foo|bar|' echo foo |sed 'spfoopbarp' ... all work the same. See `info sed': `\%REGEXP%' (The `%' may be replaced by any other single character.) This also matches the regular expression REGEXP, but allows one to use a different delimiter than `/'. This is particularly useful if the REGEXP itself contains a lot of `/'s, since it avoids the tedious escaping of every `/'. If REGEXP itself includes any delimiter characters, each must be escaped by a backslash (`\'). Ciao, Stefan -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
Stefan Troeger wrote:
Hi,
On Tue, Dec 28, 1999 at 06:23 -1000, George Toft wrote:
Stefan Troeger wrote:
so I try " ... | sed 's#.*\(\\)\#\1#g' added a " \ " after " ) " ^There's a dot missing. It should read sed 's#.*\(\.\)#\1#g'
Ciao, Stefan
Could someone translate this to English? I've used sed a little bit, but this intrigues me. So I checked man:
s/regexp/replacement/ Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the spe cial character & to refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.
So if the script begins with "s", then a slash must follow, right?
Actually you can use any character instead of a slash here.
echo foo |sed 's/foo/bar/' echo foo |sed 's@foo@bar@' echo foo |sed 's.foo.bar.' echo foo |sed 's|foo|bar|' echo foo |sed 'spfoopbarp' ..
all work the same. See `info sed':
`\%REGEXP%' (The `%' may be replaced by any other single character.)
This also matches the regular expression REGEXP, but allows one to use a different delimiter than `/'. This is particularly useful if the REGEXP itself contains a lot of `/'s, since it avoids the tedious escaping of every `/'. If REGEXP itself includes any delimiter characters, each must be escaped by a backslash (`\').
Ciao, Stefan
OK. I'm 10 points smarter (read Unix Shell Programming about regular expressions). Why did you make the replacement text \1 when . would do? $ echo "./top/001/abcdef.txt" |sed 's#.*\(\.\)#.#g' .txt $ -- George Toft http://www.georgetoft.com -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
George Toft wrote:
Stefan Troeger wrote:
[...]
it should read sed 's#.*\(\.\)#\1#g'
Ciao, Stefan
Could someone translate this to English? I've used sed a little bit, but this intrigues me. So I checked man:
s/regexp/replacement/ Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the spe cial character & to refer to that portion of the pattern space which matched, and the special escapes \1 through \9 to refer to the corresponding matching sub-expressions in the regexp.
So if the script begins with "s", then a slash must follow, right?
Actually you can use any character instead of a slash here.
echo foo |sed 's/foo/bar/' echo foo |sed 's@foo@bar@' echo foo |sed 's.foo.bar.' echo foo |sed 's|foo|bar|' echo foo |sed 'spfoopbarp' [...9 OK. I'm 10 points smarter (read Unix Shell Programming about regular expressions). Why did you make the replacement text \1 when . would do? $ echo "./top/001/abcdef.txt" |sed 's#.*\(\.\)#.#g' .txt
You are quite correct, the above is better done with expr though in which case the \(\) are more important:
expr match "./top/001/abcdef.txt" '.*\(\.[^.]*\)$' .txt
/Michael -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
Hi, On Tue, Dec 28, 1999 at 18:36 -1000, George Toft wrote:
OK. I'm 10 points smarter (read Unix Shell Programming about regular expressions). Why did you make the replacement text \1 when . would do? $ echo "./top/001/abcdef.txt" |sed 's#.*\(\.\)#.#g' .txt $
OK, that's another 10 points for you ;-) While we're talking about simplification, one could also get away without the g: [sttr]/home/sttr> echo "./top/001/abcdef.txt" |sed 's#.*\.#.#' .txt Ciao, Stefan -- To unsubscribe send e-mail to suse-linux-e-unsubscribe@suse.com For additional commands send e-mail to suse-linux-e-help@suse.com Also check the FAQ at http://www.suse.com/Support/Doku/FAQ/
participants (6)
-
grtoft@yahoo.com
-
JerryKreps@alltel.net
-
khadji@pld.com
-
Michael.Salmon@uab.ericsson.se
-
stefan.troeger@wirtschaft.tu-chemnitz.de
-
sttr@sttr.de