-1

Why does the following gives the line I am searching:

grep '<appointment-id internal:ref=1.2.3/>' test.xml  
OUTPUT is <appointment-id internal:ref=1.2.3/>  

While the following breaks it into 2 lines?

a=($(grep '<appointment-id internal:ref=1.2.3/>' test.xml))  
for i in "${a[@]}"; do  
    echo "checking $i"   
    grep  -n "$i" delete.xml
done    

The output is:

checking <appointment-id
checking internal:ref=1.2.3/>

The file is:

<note>  
    <to>Jim</to>  
    <from>John</from>  
    <heading>Reminder</heading>  
    <body>Some text</body>  
    <appointment-id internal:ref=1.2.3/> 
</note>

marked as duplicate by αғsнιη, Stephen Kitt, roaima, Jesse_b, ilkkachu bash Jun 7 '18 at 20:40

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    because word splitting happening per default IFS=$' \t\n'. see What is the 'IFS'? – αғsнιη Jun 7 '18 at 19:03
  • The first solution in How to loop over the lines of a file? should work in this case too, to fill the array. The second could be used directly, without an array at all, or to build the array with array extension (a+=("$line")). – ilkkachu Jun 7 '18 at 19:50
4

The output of the grep is a string containing two whitespace-separated words.

The shell will split that into two words since it's unquoted, and the array will therefore have two entries.

This will do what you want:

a=( "$( grep -F '<appointment-id internal:ref=1.2.3/>' test.xml )" )  

However, parsing XML with grep is a horrible idea. Use a proper XML parser instead.

Also, the loop, if all it does is outputting a string, may be replaced by

printf 'checking %s\n' "${arr[@]}"

To see who made a change to a line matching a pattern in a particular revision of a git-controlled file (see comments below), use git blame -L with the pattern and revision in question. See git blame --help for further info.


Also note that to get the line number of a line matching a pattern:

sed -n '/pattern/=' file

Don't ever feed the result of grep into grep again just to get the line number. If doing so, be sure to use grep -F, or it will fail if the line contains regular expression patterns.

Not the answer you're looking for? Browse other questions tagged or ask your own question.