Results 1 to 8 of 8

Thread: bash script to iterate through files and add a line

  1. #1
    Join Date
    Sep 2008
    Beans
    540
    Distro
    Kubuntu 12.04 Precise Pangolin

    bash script to iterate through files and add a line

    #!/bin/bash
    FILES="*"
    for f in "$FILES"
    do
    sed -n 'l i Subject: Your Daily Book Part' $f
    cat $f
    done

    What am I doing wrong here? I go to the directory I want to iterate through, and run this script. Nothing happens. I want to add that line, "Subject: Your Daily Book Part", as the first line in each of the text files in that directory.
    Registered Linux User #479009
    Friend-->Linux; 6 and counting...

  2. #2
    Join Date
    Nov 2009
    Location
    /dev/null
    Beans
    74

    Re: bash script to iterate through files and add a line

    what do you mean by nothing happens ?
    if you mean the contents of the files didn't get changed, it's because you didn't redirect the result from sed to new files.

  3. #3
    Join Date
    Sep 2008
    Beans
    540
    Distro
    Kubuntu 12.04 Precise Pangolin

    Re: bash script to iterate through files and add a line

    I thought that's what I was doing with $f. Is that not supposed to be the name of the new file?
    Registered Linux User #479009
    Friend-->Linux; 6 and counting...

  4. #4
    Join Date
    Nov 2009
    Location
    /dev/null
    Beans
    74

    Re: bash script to iterate through files and add a line

    Sed doesn't modify the contents of input files. It just outputs the modified result to the STDOUT and you need to redirect the result to new files.

    Try this

    Code:
    sed -e '1s/^/Whatever comments\n/' $f > newfile
    cat newfile
    Last edited by lostinxlation; June 11th, 2010 at 08:16 AM.

  5. #5
    Join Date
    Jun 2010
    Beans
    181

    Re: bash script to iterate through files and add a line

    Quote Originally Posted by lostinxlation View Post
    Sed doesn't modify the contents of input files.
    Sed has -i option, that overrides its normal behavior (in-place editing) see manpages.

  6. #6
    Join Date
    Sep 2008
    Beans
    540
    Distro
    Kubuntu 12.04 Precise Pangolin

    Re: bash script to iterate through files and add a line

    #!/bin/bash
    FILES="*"
    for f in "$FILES"
    do
    sed -e '1s/^/Subject:Your Daily Book Part, Tarah.\n/' $f > $f
    cat $f
    done

    It's still not working. I understand that I need to redirect the output, but I want the output to have the same name. Why doesn't this work?
    Registered Linux User #479009
    Friend-->Linux; 6 and counting...

  7. #7
    Join Date
    Mar 2006
    Location
    Eefde, The Netherlands
    Beans
    432
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: bash script to iterate through files and add a line

    As tomazzi already mentioned, sed has the -i/--in-place option:

    Code:
    for f in * ; do
        sed -i '1s/^/Subject:Your Daily Book Part, Tarah.\n/' "$f"
        cat "$f"
    done
    The -i option tells sed to do its work `in-place', in other words, to modify the file(s) it is given. The -i option takes an optional argument that specifies a backup file suffix, for example -i.bak would tell sed to backup its input file(s) with a .bak suffix.

    Redirecting the output to the same file used as sed's input most likely doesn't work because the input file is opened read-only by sed (when not using -i), so writing to the file fails.

    You could simulate the behaviour of -i by using a temporary file:
    Code:
    for f in * ; do
        sed -e '1s/Blabla/' "$f" > "$f.$$"
        if [ "$?" -eq "0" ]; then
            mv -f "$f.$$" "$f"
        fi
    done
    "When in doubt, use brute force."

    -- Ken Thompson

  8. #8
    Join Date
    Feb 2007
    Beans
    4,045
    Distro
    Ubuntu 9.10 Karmic Koala

    Re: bash script to iterate through files and add a line

    globs are not expanded when you quote them. E.g. try:
    Code:
    echo '*' "*" *
    So your for-loop should look like
    Code:
    for f in *; do ...; done
    The second problem is this:
    Code:
    sed -e '1s/^/Subject:Your Daily Book Part, Tarah.\n/' $f > $f
    Ok, bash sees you want to redirect output from some command to a file $f, so it opens the file for writing, which truncates it (empties it), then starts the sed program with at least 3 arguments. Sed now tries to read the same file $f which is empty, so it completes. You must use a temporary file.

    Now, that is of course if $f happens to be one filename that does not contain any special characters like spaces or globs (in your case it contains *, which is expanded to all files in the current dir). Always quote parameter expansions; "$f", not $f.

    To prepend a line to a file see this:
    http://mywiki.wooledge.org/BashFAQ/090

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •