Reputation: 31
I'm not good at bash shell scripting in Ubuntu, so I need your help.
The problem is...
We use Perforce for SCM.
I try to get directories from //Development/
branches.
Until this time, everything was good.
But now I can't split branches by whitespace anymore, because of branches such as the following (note the embedded space):
//Development/graphic/release/Unity Provider
We need each branch on a separate line starting with //Development
, but always I get the following result (note the unwanted line break):
//Development/graphic/release/Unity Provider
How can I fix this?
Please help me. Thank you.
Below is a sample one-line string:
//Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/graphic/release/Core //Development/graphic/release/Provider //Development/graphic/release/WH //Development/graphic/release/Accessory //Development/graphic/release/Unity Provider //Development/graphic/release/tipManager
And, I want to get a result string like below (each branch name on its own line):
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager
I also want to store the results in a list variable.
E.g., list[0]
should contain //Development/graphic/release/CM
.
Upvotes: 0
Views: 100
Reputation: 439317
I'm assuming that:
//[Development/]
, either at the start of the string, or, if inside, preceded by a single space.//[Development/]
instances contain spaces or not.str='//Development/graphic/release/CM //Development/graphic/release/GManager //Development/graphic/release/Notification //Development/graphic/release/Core //Development/graphic/release/Provider //Development/graphic/release/WH //Development/graphic/release/Accessory //Development/graphic/release/Unity Provider //Development/graphic/release/tipManager'
echo "$str" | sed 's# \(//\)#\'$'\n''\1#g'
The above should work with any POSIX-compatible sed
implementation.
To capture the output in a variable, using command substitution:
result=$(echo "$str" | sed 's# \(//\)#\'$'\n''\1#g')
If you then want to process the result line by line:
while read -r path; do echo "$path"; done <<<"$result"
Explanation of the sed
command:
#
was - arbitrarily - chosen as the delimiter for sed
's s
(string substitution) command so as to make it easier to match /
chars (customarily, /
is used as the delimiter, which would necessitate \
-escaping /
instances in the regex and replacement string). \(//\)
matches //
if preceded by a space, i.e., inside the string.\'$'\n''
effectively inserts a newline (\n
) into the replacement string, using ANSI C quoting (required for OSX compatibility; on Linux, just \n
would do).\1
inserts the 1st (and only) capture group from the regex, i.e, //
g
ensures that matching is global, i.e., that all substrings that match the regex are replaced.Result:
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager
Upvotes: 1
Reputation: 174786
You could try this awk command also,
$ awk -v RS=" //" '{gsub (/^D/,"//D");}1' file
//Development/graphic/release/CM
//Development/graphic/release/GManager
//Development/graphic/release/Notification
//Development/graphic/release/Core
//Development/graphic/release/Provider
//Development/graphic/release/WH
//Development/graphic/release/Accessory
//Development/graphic/release/Unity Provider
//Development/graphic/release/tipManager
Upvotes: 0
Reputation: 314
Use the Internal Field Separator (IFS) Variable to break on newline instead of white space.
This explains it well: http://mindspill.net/computing/linux-notes/using-the-bash-ifs-variable-to-make-for-loops-split-with-non-whitespace-characters/
An example pulled from the link above:
#!/bin/bash
IFS=$','
vals='/mnt,/var/lib/vmware/Virtual Machines,/dev,/proc,/sys,/tmp,/usr/portage,/var/tmp'
for i in $vals;
do echo $i;
done
unset IFS
Upvotes: 0