Reputation: 1620
I have a file that has a certain string on some lines that takes the form of either [Name](./path_to_name_directory)
or [Name](./path_to_name_directory/notes.md)
each with some unimportant list items. For the lines that do not have notes.md
at the end of the file path within the parenthesis, Name
gets prepended to that line.
To try and solve this, I originally had the following command
sed 's/\[(.*)\]\(\.\/.*\/(?!notes\.md)/\1&/g' ./file.md
but I eventually found out that sed does not support lookaheads or lookbehinds, so I moved to using perl to try and accomplish the same. I thought it would be as simple as doing
perl -pe 's/\[(.*)\]\(\.\/.*\/(?!notes\.md)/\1&/g'
but it did not work, and I'm not entirely sure where to go from here.
EDIT 1:
Sample Input File:
- [Name 1](./path_to_name_1)
- Unimportant list item.
- [Name 2](./path_to_name_2/notes.md)
- Unimportant list item.
Sample Output File:
- Name 1 [Name 1](./path_to_name_1)
- Unimportant list item.
- [Name 2](./path_to_name_2/notes.md)
- Unimportant list item.
Upvotes: 3
Views: 513
Reputation: 1126
With awk
, you can set FS
as [][]|/|)
. This way you can get the content of $2
and $5
and put the condition.
awk -v FS='[][]|/|)' '$2 ~ /^Name [[:digit:]]/ && $5 !~ /notes.md/ {sub(/^. /, "&"$2" " , $0)} 1' file
- Name 1 [Name 1](./path_to_name_1)
- Unimportant list item.
- [Name 2](./path_to_name_2/notes.md)
- Unimportant list item.
Upvotes: 1
Reputation: 1620
An option that I came up with using @ RavinderSingh13's answer and this related answer is the following
sed -E '/.*notes\.md.*/!s/\[(.*)\]/\1&/g'
/.*notes\.md.*/!
tells sed
to not match if the string matches that regex. In other words, sed
will only match lines that do not match the address specification (See code block #5 of section 4.1 of the GNU Sed Manual).
s/\[(.*)\]/\1&/g
tells sed
to capture group the inner string of the square brackets and prepend it to the entire match; the portion of the regex that accomplishes the positional placement is \1&
, where \1
is the capture group, and &
references the entire matched portion of the string.)
Upvotes: 1
Reputation: 133518
With your shown samples, please try following.
awk '
!/notes\.md\)$/ && match($0,/\[Name [0-9]+/){
$1=$1 OFS substr($0,RSTART+1,RLENGTH-1)
}
1
' Input_file
Explanation: Adding detailed explanation for above. This is only for explanation purposes.
awk '
##Starting awk program from here.
!/notes\.md\)$/ && match($0,/\[Name [0-9]+/){
##Checking condition if current does not end with notes.md) then match [Name digits in current line.
$1=$1 OFS substr($0,RSTART+1,RLENGTH-1)
##Re-create 1st field which has current $1 OFS and sub string of matched regex value.
}
1
##This will print current edited/non-edited line here.
' Input_file ##Mentioning Input_file name here.
Upvotes: 3