Reputation: 1698
In my shell script I pipe the output of a for loop into an embedded sed command with a long "s|||" substitution statement, as follows:
#/usr/bin/bash
output=/cygdrive/c/output.csv
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e "s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)|$i,\1,\2-\3-\4,\2,\3,\4,\5|"
done >> $output
The sed command is too long, so my question is how do I wrap the sed line across multiple lines within breaking it?
For example:
#/usr/bin/bash
output=/cygdrive/c/output.csv
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e
"s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)
|$i,\1,\2-\3-\4,\2,\3,\4,\5|"
done >> $output
Upvotes: 2
Views: 1205
Reputation: 26707
You can keep your original script, using continuation character, without resorting to additional shell variables:
sed -e \
"s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\
\([0-9]\+\)\.bfc\ \([0-9]\+\)\
|$i,\1,\2-\3-\4,\2,\3,\4,\5|"
Upvotes: 3
Reputation: 614
a} You can use the "" symbol (without quotes) to cause a line to wrap to the end.
b} If you give me a more detailed example of what you're actually doing, I can 90% promise you that there is a simpler solution to the problem than that regular expression.
I only use regexes if I am only trying to match one or two things at a time. If I need something more complex, then I will first use a simple regex in ed to get as close in the file as I can, and then use relative line numbering to go the rest of the way, extract the relevant lines(s) with ed, alter them as needed with other programs, and then either just use the newly created file, or merge the alterations back in with the original.
Upvotes: 0
Reputation: 1698
I couldn't format the code nicely in my comment above so here is what I did which works:
#/usr/bin/bash
output=/cygdrive/c/output.csv
PATTERN="^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)"
REPLACE="\1,\2-\3-\4,\2,\3,\4,\5"
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.bfc" -printf "%p %k\n" |
sed -e "s|$PATTERN|$i,$REPLACE|"
done >> $output
Thanks Jose B. for your answer above.
Upvotes: 0
Reputation: 407
Can you put that specific string in a variable like:
SED_PATTERN="s|^.\+/\([A-Z]\+\)/\(20..\)/\([0-9]\+\)-\([0-9]"
SED_PATTERN+="\+\)-\([0-9]\+\)\.bfc\ \([0-9]\+\)"
SED_PATTERN+="|$i,\1,\2-\3-\4,\2,\3,\4,\5|"
for i in a b {d..z}
do
find /cygdrive/$i -type f -name "*.ext" -printf "%p %k\n" |
sed -e "$SED_PATTERN"
done >> $output
I think that would be the cleanest way.
Upvotes: 5