The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - Newcomers (http://hintsforums.macworld.com/forumdisplay.php?f=15)
-   -   Piping ls and sed to mv (http://hintsforums.macworld.com/showthread.php?t=102528)

wagghers 06-14-2009 08:17 AM

Piping ls and sed to mv
 
I'm trying to rename some files in MUSIC directory using eg:-



ls | sed -e's/Beethoven_ Symphony/Symph/' -e's/Minor/Min/'



Can I then pass the original filename and sed's output to mv?

If not, any advice on how best to do this

Ta

hayne 06-14-2009 10:46 AM

You'd be best to write a script instead of trying to do it all as a one-liner.
Then you could simply define a variable to hold the result of the above command and then use that variable with 'mv'.
Something like:

filename=$(ls | sed -e's/Beethoven_ Symphony/Symph/' -e's/Minor/Min/')
mv $filename /somewhere/over/the/rainbow

But if you insist, you could combine these into one line:
mv $(ls | sed -e's/Beethoven_ Symphony/Symph/' -e's/Minor/Min/') /somewhere/over/the/rainbow

wagghers 06-14-2009 04:30 PM

Thanks hayne, doesn’t do quite what I want; I’ll try to explain a bit better…

I’ve got a directory with these files in it -

my-imac:TryMv me$ ls
01 Beethoven_ Symphony #5 In C Minor, Op. 67.m4a
02 Beethoven_ Symphony #5 In C Minor, Op. 67.m4a
03 Beethoven_ Symphony #5 In C Minor, Op. 67.m4a
04 Beethoven_ Symphony #5 In C Minor, Op. 67.m4a

If I pipe ls to sed I get -

my-imac:TryMv me$ (ls | sed -e's/Beethoven_ Symphony/Symph/' -e's/Minor/Min/')
01 Symph #5 In C Min, Op. 67.m4a
02 Symph #5 In C Min, Op. 67.m4a
03 Symph #5 In C Min, Op. 67.m4a
04 Symph #5 In C Min, Op. 67.m4a

So what I want to do is rename each one of the files using mv into the filenames that sed outputs. Can I do this?
If I put ls | sed… into a variable, it puts all the files together, I think, but I want them individually.

ghostdog74 06-14-2009 08:43 PM

no need sed if using bash.
Code:

for files in *
do
  old=$files
  files=${files/Beethoven_ Symphony/Symph}
  files=${files/Minor/Min}
  mv "$old" "$files"
done


acme.mail.order 06-14-2009 11:28 PM

A very useful technique is to build the command you need and have it output the results. like this:
Code:

ls -1 | sed -e 's/\(..\) Beethoven_ Symphony \(..\) In \([ABCDEFG#]* ...\).*\(Op.*\)/mv "\0" "\1 Symph \2 In \3, \4"/'
When you are happy with the results, just re-run the command ( up arrow for history) and add ` | bash ` at the end.

Avoids cases where one tiny typo renames everything to the same name, thus wiping out the entire directory :rolleyes:

ghostdog74 06-15-2009 01:51 AM

maybe ok for 1 file. If there are lots of files to change common terms , using multiple pipes, coupled with the fact that it will call the bash interpreter for 1000 , 2000 etc times (for 1000,2000 files found with the pattern) will make the script inefficient.

acme.mail.order 06-15-2009 02:03 AM

bash only gets called once, at the end of the pipe. And it simply receives a command list.

Also, efficiency for a one-time rename job is rather irrelevant - it's still faster than renaming by hand.

ghostdog74 06-15-2009 04:11 AM

Quote:

Originally Posted by acme.mail.order (Post 538138)
bash only gets called once, at the end of the pipe. And it simply receives a command list.

Also, efficiency for a one-time rename job is rather irrelevant - it's still faster than renaming by hand.


maybe my english is bad , what i am wanting to say is there should be a way using xargs to get those sed output to bash. I am sure you know what xargs is for. that's all there is.

acme.mail.order 06-15-2009 04:42 AM

mv is a bash builtin, xargs is a separate program that feeds things to other programs, including bash and mv.

My method feeds a command list directly to bash, so it's just as efficient as a script file containing full hardcoded commands, and that's about as efficient as bash gets.

Plus, you have the development advantage of seeing exactly what the shell will see - rather important with dangerous commands like mv.

ghostdog74 06-15-2009 05:06 AM

mv is not a bash builtin.

acme.mail.order 06-15-2009 05:36 AM

guess what - it's not. Must have been thinking of the other sundry 2-letter builtins.

wagghers 06-15-2009 07:44 PM

Quote:

Originally Posted by acme.mail.order (Post 538124)
A very useful technique is to build the command you need and have it output the results. like this:
Code:

ls -1 | sed -e 's/\(..\) Beethoven_ Symphony \(..\) In \([ABCDEFG#]* ...\).*\(Op.*\)/mv "\0" "\1 Symph \2 In \3, \4"/'

Slowly getting my head round that, looks great though, good for my learning curve.

What doesn't seem to work is the "\0" which just outputs... well "0" rather than the original filename. Any ideas why?

acme.mail.order 06-15-2009 07:58 PM

\0 should output the entire matched expression. If it is producing a literal '0' then you may have an old version of sed.

sed --version

If it says 'illegal option' then you have an ancient version, missing all sorts of useful stuff.

wagghers 06-15-2009 08:49 PM

Ah yes, seems I have an old version...

How do I update?

Hal Itosis 06-15-2009 10:39 PM

Quote:

Originally Posted by acme.mail.order (Post 538262)
\0 should output the entire matched expression. If it is producing a literal '0' then you may have an old version of sed.

sed --version

If it says 'illegal option' then you have an ancient version, missing all sorts of useful stuff.

"Ancient"?

Since when is \0 a match for the entire regexp in sed?
\&
is what i seem to recall. [i should doublecheck, but
it's just that today is the first i'm hearing about \0, and
the (2005) book i used to learn about sed isn't ancient.]

edit:
a quick check shows & (not \&) is what i should have sed. ;)

acme.mail.order 06-15-2009 11:25 PM

Quote:

Originally Posted by Hal Itosis (Post 538280)
a quick check shows & (not \&) is what i should have sed. ;)

Very hard smack on the head with the O'Reilley Owl book.

Hal Itosis 06-15-2009 11:47 PM

repeat: Since when is \0 a match for the entire regexp in sed? :confused: We know awk uses $0.

[or did i misunderstand your last communiqué? -- i was more right than wrong, right?]

And if \0 is the latest craze... surely & wasn't deprecated into instant extinction, was it?

acme.mail.order 06-16-2009 12:27 AM

Doesn't appear to be depreciated, I use \0 in other regex to match the whole string and it works with the current version of sed.

So, it appears we are both right as & works in the Apple-supplied version of sed and \0 (and & ) work in the latest version.

Quote:

Originally Posted by mervTormel (Post 98277)
one doesn't learn sed. one pokes a stick at it.


Hal Itosis 06-16-2009 12:54 AM

Okay (thanks!)... well, it's still news to me.

Perhaps it's some special Gnu extension... i don't see any mention of \0 in man regex either (hard to google for "\0" -- can you link to a page where it gets mentioned... and perhaps the "since when" question gets answered?). Is it specific to BRE, ERE, only certain commands, or only Gnu versions of certain commands?

acme.mail.order 06-16-2009 02:44 AM

Dunno - it's worked on almost every regex I've used in recent memory. Never heard of & as matching the whole expression before today.

jbc 06-16-2009 09:55 AM

On my Tiger setup, \0 does *not* work with the default installed sed. However, it works fine with the MacPorts-installed gsed (GNU sed) without using ERE's. The gsed man page contains only this:
Code:

      s/regexp/replacement/
              Attempt  to match regexp against the pattern space.  If success-
              ful,  replace  that  portion  matched  with  replacement.    The
              replacement may contain the special 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.

There's no mention of \0, although it seems to work. The gsed man page lists the version as 4.1.4, February 2006.

Hal Itosis 06-16-2009 07:02 PM

Quote:

Originally Posted by jbc (Post 538334)
On my Tiger setup, \0 does *not* work with the default installed sed. However, it works fine with the MacPorts-installed gsed (GNU sed) without using ERE's. The gsed man page contains only this:

s/regexp/replacement/

Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special 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.

There's no mention of \0, although it seems to work. The gsed man page lists the version as 4.1.4, February 2006.

And the ancient OSX sed says:
Quote:

[2addr]s/regular expression/replacement/flags

Substitute the replacement string for the first instance of the regular expression in the pattern space. Any character other than backslash or newline can be used instead of a slash to delimit the RE and the replacement. Within the RE and the replacement, the RE delimiter itself can be used as a literal character if it is preceded by a backslash.

An ampersand (``&'') appearing in the replacement is replaced by the string matching the RE. The special meaning of ``&'' in this context can be suppressed by preceding it by a backslash. The string ``\#'', where ``#'' is a digit, is replaced by the text matched by the corresponding backreference expression (see re_format(7)).

...so, & is mentioned in both man pages (as well as every tutorial i ever read, such as).

Where is \0 documented?

[as both man pages above go on to say, escaped numbers like \1 \2 \3 etc., are used for back references to portions captured within \( parens \). I can see where \0 is a cool notation for the whole RE... i just don't see where that convention was ever established.]


All times are GMT -5. The time now is 10:17 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.