Help with sed


 
Thread Tools Search this Thread
Top Forums UNIX for Dummies Questions & Answers Help with sed
# 1  
Old 03-23-2014
Help with sed

Hi, I am trying to create a script that will do some edits on files (playlists) in a directory and save the new file in a new directory.

What I am trying to accomplish:
1. for all files ending in .m3u8 in /mnt/music/playlists/madsonic
2. replace all occurrences of "/mnt" with "//10.0.10.91"
3. write the modified file to /mnt/music2 with the original filename except with .m3u file extension

I plan to use cron to have this run every 5 minutes or so. The os is Debian 7.3. I have made some attempts with sed but have only successfully created one file that mashed all my playlists together... Here is what I have managed so far:

Code:
#!/bin/sh
MADSONICPLAYLISTS=/mnt/music/playlists/madsonic/*
for *.m3u8 in $MADSONICPLAYLISTS 
   sed -n '
      s|
      /mnt|
      //10.0.10.91|
      gpw '/mnt/music2/$MADSONICPLAYLISTS.m3u' $MADSONICPLAYLISTS.m3u
done

Thanks in advance for any assistance!
Jason
# 2  
Old 03-23-2014
You might want to read an "sed" primer as well as a shell introduction...

In this case you do not need "sed" at all.
try:

Code:
#!/bin/sh
MADSONICPLAYLISTS="/mnt/music/playlists/madsonic"
FILE=""
echo > /path/to/playlist.file
for FILE in $MADSONICPLAYLISTS/*.m3u8 ; do
     echo "//10.0.10.91/${FILE#/*/*}" >> /path/to/playlist.file
done

The first "echo" zaps the existing playlist-file, the subsequent "echo"'s fill it again. Have a look into the file if this is what you want.

I hope this helps.

bakunin
This User Gave Thanks to bakunin For This Post:
# 3  
Old 03-23-2014
Thanks for the quick reply bakunin. I was attempting to use sed as I can make it work easily for a single file, but I was having difficulty figuring out how to run it for all files in a directory, and save the output to the same filename in a different directory.

I don't understand how your code is going to do what I want. Re-reading my original post, I may have been unclear.

For example, this is /mnt/music/playlists/madsonic/Rock.m3u8:
Code:
#EXTM3U
#EXTINF:212,Steppenwolf - Born to Be Wild
/mnt/music2/Steppenwolf/Steppenwolf/05 Born to Be Wild.flac
#EXTINF:453,Lynyrd Skynyrd - Tuesday's Gone
/mnt/music2/Lynyrd Skynyrd/The Definitive Lynyrd Skynyrd Collection/1-13 Tuesday's Gone.mp3
#EXTINF:241,Kansas - Dust in the Wind
/mnt/music2/Kansas/Always Never the Same/02 Kansas - Dust in the Wind.flac
#EXTINF:249,Journey - Don't Stop Believin'
/mnt/music2/Journey/Greatest Hits/02 Don't Stop Believin'.mp3

Each .m3u8 file in /mnt/music/playlists/madsonic has lines that start with "/mnt" which I want to simply replace with "//10.0.10.91".

Then save the new file with lines modified to /mnt/music2, keeping the file name and changing the extension to .m3u. So the above would then be located at /mnt/music2/Rock.m3u.

Thanks for helping a novice!
# 4  
Old 03-24-2014
Quote:
Originally Posted by jay3712
Thanks for the quick reply bakunin. I was attempting to use sed as I can make it work easily for a single file, but I was having difficulty figuring out how to run it for all files in a directory, and save the output to the same filename in a different directory.
OK, it becomes clearer now what you really want. Sorry, but i simply misunderstood your intention.

Quote:
Originally Posted by jay3712
For example, this is /mnt/music/playlists/madsonic/Rock.m3u8:
Code:
#EXTM3U
#EXTINF:212,Steppenwolf - Born to Be Wild
/mnt/music2/Steppenwolf/Steppenwolf/05 Born to Be Wild.flac
#EXTINF:453,Lynyrd Skynyrd - Tuesday's Gone
/mnt/music2/Lynyrd Skynyrd/The Definitive Lynyrd Skynyrd Collection/1-13 Tuesday's Gone.mp3
#EXTINF:241,Kansas - Dust in the Wind
/mnt/music2/Kansas/Always Never the Same/02 Kansas - Dust in the Wind.flac
#EXTINF:249,Journey - Don't Stop Believin'
/mnt/music2/Journey/Greatest Hits/02 Don't Stop Believin'.mp3

Each .m3u8 file in /mnt/music/playlists/madsonic has lines that start with "/mnt" which I want to simply replace with "//10.0.10.91".

Then save the new file with lines modified to /mnt/music2, keeping the file name and changing the extension to .m3u. So the above would then be located at /mnt/music2/Rock.m3u.
Understood. We do not write code for others here, but spread the knowledge about how to write code yourself, so i am going to do it slowly and i will explain every step. You are encouraged to try every single step of the scripts development and modify it a bit to understand how it works:

Let us start with the input- and the output files to make sure the files are read from and put into the correct place. We cycle through all the prospective input files, which will reside in a certain directory and have a certain extension. We will just display the found filenames - to make clear the way the mechanism works and also to give you the opportunity to check if these are really the file names you want to be found (btw.: i myself develop my scripts this way - by gradually implementing one goal after the other - so there is nothing wrong with it):

Code:
#! /bin/bash
typeset fIn="/mnt/music/playlists/madsonic"
typeset chFile=""
typeset chExtIn="m3u8"

for chFile in "$fIn"/*"$chExtIn" ; do
     echo "$chFile"
done

exit 0

The for-loop sets the variable "fInFile" to the name of each file you want to change. The inner part of the loop just prints this filename, so you can check if this catches all the files you want to have caught. If there are more or less or other files we would have to stop here and modify the file mask somehow, otherwise - if everything is OK - we can proceed.

Now, there is a simple pattern between the name and path to the input file and the name and the path of the output file. For such patterns and when we want to manipulate variables there is a better tool than "sed": variable expansion. I suggest you get a primer book for shell programming and read up how this works there, because the man page is a good reference but a poor teaching tool. Basically it works like that: you can cut off the leading or trailing part of a variable, where "part" is a certain pattern you specify - for instance "the first (last) three characters" or "up to the last/first space char", etc.. I have used comments to explain what exactly i am doing. Try what i do :

Code:
#! /bin/bash
typeset fIn="/mnt/music/playlists/madsonic"
typeset chExtIn="m3u8"
typeset fOut="/mnt/music2"
typeset chExtOut="m3u"
typeset chFile=""

for chFile in "$fIn"/*"$chExtIn" ; do
     chFile="${chFile##*/}"                  # cut off the path, leaving "filename.ext"
     chFile="${chFile%.*}"                   # cut off the extension, leaving "filename"
     echo "input: ${fIn}/${chFile}.${chExtIn}  /// output: ${fOut}/${chFile}.${chExtOut}"
done

exit 0

Again: try to understand how the various pieces work together, play around with it, put additional "print"-statements into the code to watch how the variables change their values, etc.. If you satisfied we can proceed to the last step: modifying the files.

What you want to do with "sed" is in no way different than doing it from teh command line: suppose you have a file "a" and you want to change it and store the resulting data to file "b". You would do:

Code:
sed '<your changes here>' a > b

Now, working inside a script and using variables we do the same. We just replace the fixed filenames "a" and "b" with our variables. Notice that i have used a "writethrough" "sed" script, which effectively does nothing but copy the unaltered contents to the result file. You might want to change "fOut" to some temporary directory for the moment so that you can easily remove the files the script creates:

Code:
#! /bin/bash
typeset fIn="/mnt/music/playlists/madsonic"
typeset chExtIn="m3u8"
typeset fOut="/mnt/music2"
typeset chExtOut="m3u"
typeset chFile=""

for chFile in "$fIn"/*"$chExtIn" ; do
     chFile="${chFile##*/}"                  # cut off the path, leaving "filename.ext"
     chFile="${chFile%.*}"                   # cut off the extension, leaving "filename"
     sed -n 'p' "${fIn}/${chFile}.${chExtIn}" > "${fOut}/${chFile}.${chExtOut}"
done

exit 0

Now, let us replace the "writethough" by some meaningfule program: you want to change some fixed string to some other fixed string, but there are some characters involved which have a special meaning to "sed". This is easily dealt with by "escaping" these characters - prepend them with a backslash: "\". So here is the final version of your script. Again, use a temporary directory first for destination and check the results before you put it to work:

Code:
#! /bin/bash
typeset fIn="/mnt/music/playlists/madsonic"
typeset chExtIn="m3u8"
typeset fOut="/mnt/music2"
typeset chExtOut="m3u"
typeset chFile=""

for chFile in "$fIn"/*"$chExtIn" ; do
     chFile="${chFile##*/}"                  # cut off the path, leaving "filename.ext"
     chFile="${chFile%.*}"                   # cut off the extension, leaving "filename"
     sed 's/^\/mnt/\/\/10.0.10.91/' "${fIn}/${chFile}.${chExtIn}" > "${fOut}/${chFile}.${chExtOut}"
done

exit 0

Some suggestions: good scripts will sense and report some possible error conditions instead of trampling through your system. For instance: what should the script do if a resultfile it is about to write does already exist? Overwrite without asking? Ask for permission interactively? Skip this certain file? Something else? This is not so much a question of how to implement it but to think your requirements through and program accordingly. This will set apart your scripts from all the mindlessly-do-some-job scripts that float around. There are many tutorials about how to write programs (scripting is just programming with a certain language), but the best advise one can give is: before you even start think through your requirements as detailed as possible and get get best possible picture in your imagination about how the program is supposed to behave.


I hope this helps.

bakunin

Last edited by bakunin; 03-24-2014 at 03:41 PM..
This User Gave Thanks to bakunin For This Post:
# 5  
Old 03-24-2014
Thanks a ton bakunin, you are a gentleman and a scholar. I really appreciate that you took the time to write out with an explanation that I can understand. This works wonderfully, and the best part is I actually understand what piece of each line is doing. I will test a bit more and add it to my cron for this machine.

Cheers!
Jason
 
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

I am learning regular expression in sed,Please help me understand the use curly bracket in sed,

I am learning SED and just following the shell scripting book, i have trouble understanding the grep and sed statement, Question : 1 __________ /opt/oracle/work/antony>cat teledir.txt jai sharma 25853670 chanchal singhvi 9831545629 anil aggarwal 9830263298 shyam saksena 23217847 lalit... (7 Replies)
Discussion started by: Antony Ankrose
7 Replies

2. Shell Programming and Scripting

sed and awk giving error ./sample.sh: line 13: sed: command not found

Hi, I am running a script sample.sh in bash environment .In the script i am using sed and awk commands which when executed individually from terminal they are getting executed normally but when i give these sed and awk commands in the script it is giving the below errors :- ./sample.sh: line... (12 Replies)
Discussion started by: satishmallidi
12 Replies

3. Shell Programming and Scripting

sed inside sed for replacing string

My need is : Want to change docBase="/something/something/something" to docBase="/only/this/path/for/all/files" I have some (about 250 files)xml files. In FileOne it contains <Context path="/PPP" displayName="PPP" docBase="/home/me/documents" reloadable="true" crossContext="true">... (1 Reply)
Discussion started by: linuxadmin
1 Replies

4. Shell Programming and Scripting

How to use sed to replace the a string in the same file using sed?

How do i replace a string using sed into the same file without creating a intermediate file? (7 Replies)
Discussion started by: gomes1333
7 Replies

5. UNIX for Dummies Questions & Answers

SED: Can't Repeat Search Character in SED Output

I'm not sure if the problem I'm seeing is an artifact of sed or simply a beginner's mistake. Here's the problem: I want to add a zero-width space following each underscore between XML tags. For example, if I had the following xml: <MY_BIG_TAG>This_is_a_test</MY_BIG_TAG> It should look like... (8 Replies)
Discussion started by: rhetoric101
8 Replies

6. Shell Programming and Scripting

deleting text records with sed (sed paragraphs)

Hi all, First off, Thank you all for the knowledge I have gleaned from this site! Deleting Records from a text file... sed paragraphs The following code works nearly perfect, however each time it is run on the log file it adds a newline at the head of the file, run it 5 times, it'll have 5... (1 Reply)
Discussion started by: Festus Hagen
1 Replies

7. Shell Programming and Scripting

sed has zeored my files. Help me with sed please

i made a script to update a lot of xml files. to save me some time. Ran it and it replaced all the the files with a 0kb file. The problem i was having is that I am using sed to change xml node <doc_root>. The problem with this is it has a / in the closing xml tag and the stuff inside will also have... (4 Replies)
Discussion started by: timgolding
4 Replies

8. Shell Programming and Scripting

sed over writes my original file (using sed to remove leading spaces)

Hello and thx for reading this I'm using sed to remove only the leading spaces in a file bash-280R# cat foofile some text some text some text some text some text bash-280R# bash-280R# sed 's/^ *//' foofile > foofile.use bash-280R# cat foofile.use some text some text some text... (6 Replies)
Discussion started by: laser
6 Replies

9. Shell Programming and Scripting

Issue with a sed one liner variant - sed 's/ ; /|/g' $TMP1 > $TMP

Execution of the following segment is giving the error - Script extract:- OUT=$DATADIR/sol_rsult_orphn.bcp TMP1=${OUT}_tmp1 TMP=${OUT}_tmp ( isql -w 400 $dbConnect_OPR <<EOF select convert(char(10), s.lead_id) +'|' + s.pho_loc_type, ";", s.sol_rsult_cmnt, ";", +'|'+ s.del_ind... (3 Replies)
Discussion started by: kzmatam
3 Replies

10. Shell Programming and Scripting

Sed Question 1. (Don't quite know how to use sed! Thanks)

Write a sed script to extract the year, rank, and stock for the most recent 10 years available in the file top10_mktval.csv, and output in the following format: ------------------------------ YEAR |RANK| STOCK ------------------------------ 2007 | 1 | Exxon... (1 Reply)
Discussion started by: beibeiatNY
1 Replies
Login or Register to Ask a Question