2

I'm doing some placeholder replacements in various files that I'm feeding to ldapadd, to add new entries to an LDAP directory:

sed \
    -e 's/%%FOO%%/whatever/g' \
    -e 's/%%BAR%%/other thing/g \
    file1.ldif.template \
    file2.ldif.template \
    | ldapadd -x -D 'cn=admin,dc=example,dc=com' -W

The problem I'm having with this is that if there is not an empty line at the end of file1.ldif.template, the first record in file2 is concatenated to the last record in file1, and in ldif files different records should be separated by at least 1 newline.

Of course I could add an empty line at the end of file1, but that is very easy to fail in the future if some other developer (or their editors) remove the trailing newlines.

So to summarize. Current (simplified) sed output:

dn: cn=record1_file1,dc=example,dc=com
cn: record1_file1

dn: cn=record2_file1,dc=example,dc=com
cn: record2_file1
dn: cn=record1_file2,dc=example,dc=com
cn: record1_file2

dn: cn=record2_file2,dc=example,dc=com
cn: record2_file2

Desired (simplified) output:

dn: cn=record1_file1,dc=example,dc=com
cn: record1_file1

dn: cn=record2_file1,dc=example,dc=com
cn: record2_file1

dn: cn=record1_file2,dc=example,dc=com
cn: record1_file2

dn: cn=record2_file2,dc=example,dc=com
cn: record2_file2

I'm working on linux (fedora 21) using GNU sed. Portability is not a concern (but i'll prefer a portable solution over a GNU solution).

2 Answers 2

2

Using GNU sed -s (--separate) extension, you can append an empty newline after each filename (line addresses refer to each filename, instead of treating all the input as one longer stream, similar to awk's FNR and NR variables)

sed \
    -s \
    -e '$a\\' \
    -e 's/%%FOO%%/whatever/g' \
    -e 's/%%BAR%%/other thing/g \
    file1.ldif.template \
    file2.ldif.template \
    | ldapadd -x -D 'cn=admin,dc=example,dc=com' -W

So using -s with -e '$a\\' is what makes sed insert a newline at the end of all input files.

2

An easy and portable way is to insert a file with an empty line in the file arguments:

# create file with one empty line
echo > emptyline.txt

# calling sed:
sed -e 's/%%FOO%%/whatever/g' \
    -e 's/%%BAR%%/other thing/g \
    file1.ldif.template \
    emptyline.txt \
    file2.ldif.template \ 
    | ...

Some shells support also this:

sed -e 's/%%FOO%%/whatever/g' \
    -e 's/%%BAR%%/other thing/g \
    file1.ldif.template \
    <(echo) \
    file2.ldif.template \ 
    | ...
4
  • This is becoming rather inconvenient with many file names (as mentioned here) or even complex if the list of files is passed to sed via xargs/find... Jul 3, 2015 at 13:21
  • @don_crissti I added a possiblity with xargs for many files.
    – jofel
    Jul 3, 2015 at 14:04
  • Errhh... I was talking about passing multiple file names to a single sed invocation; that looks like some complex code that spawns a shell which runs cat, echo & sed for each file - but then, if you're processing each file separately (that is, one sed per file) you can simply do -exec sed -e 'blah-blah' -e '$a\\' {} \; (which is exactly what OP does but with a single gnu sed invocation) Jul 3, 2015 at 14:30
  • @don_crissti yes your are correct, it does not make sense, I removed it.
    – jofel
    Jul 3, 2015 at 15:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .