Reputation:
I want to get the line number of the pattern "\label
" with "grep -n
" into a file.
The file content is :
\begin{equation}
(\beq{f'_{i}})_{3}-(\beq{e_{i}})_{3}=\text{d}\delta\,\beq{e_{i}}-\delta\,\text{d}\beq{e_{i}}
\label{r58}
\end{equation}
...
\begin{align}
&\beq{mm'_{3}}-\beq{mm_{3}}=\text{d}\delta\,\beq{m}-\delta\,\text{d}\beq{m}
\label{r59} \\
&(\beq{e'_{i}})_{3}-(\beq{e_{i}})_{3}=\text{d}\delta\,\beq{e_{i}}-\delta\,\text{d}\beq{e_{i}}
\label{r60}
\end{align}
...
\begin{equation}
(\beq{g'_{i}})_{3}-(\beq{e_{i}})_{3}=\text{d}\delta\,\beq{e_{i}}-\delta\,\text{d}\beq{e_{i}}
\label{r61}
\end{equation}
...
The command that I use :
for k in $(grep -n '\\label' test.tex); do echo $k; done
and I get :
...
1366:\label{r58}
1376:\label{r59}
\\
1378:\label{r60}
1388:\label{r61}
...
and I want :
...
1366:\label{r58}
1376:\label{r59}
1378:\label{r60}
1388:\label{r61}
...
Given that I handle after the value of k variable
, I would like to skip the line with a double backslash, it seems that "grep -n
" interprets the double backslash.
I know that I could do a pipe command on k
like "grep -v '\\\\
' but can I directly skip this double backslash with grep -n
(with an additional flag or with a more explicit pattern) ?
Thanks
Upvotes: 0
Views: 139
Reputation: 3474
Since this question is tagged with Bash, I assume you're using the Bash shell.
The following code will take input_file.txt
as an input file, and create output_file.txt
containing a list of line numbers matching your pattern.
while read -r line;do printf '%s\n' "${line%%:*}";done < <(grep -n --fixed-strings '\label' input_file.txt) > output_file.txt
P.S.
Regarding the code you posted in the question:
Never do this: for x in $(command)
or command
or $var. for-in is used for iterating arguments, not (output) strings. Instead, use a glob (eg. *.txt), arrays (eg. "${names[@]}"
) or a while-read
loop (eg. while read -r line
). See http://mywiki.wooledge.org/BashPitfalls#pf1 and http://mywiki.wooledge.org/DontReadLinesWithFor
Upvotes: 0
Reputation: 52211
You can fix the issue with the newline with
$ for k in "$(grep -n '\\label' text.tex)"; do echo "$k"; done
3:\label{r58}
10:\label{r59} \\
12:\label{r60}
19:\label{r61}
i.e., quoting the command substitution. Which is a very complicated (and not recommended) way of just using
grep -n '\\label' test.tex
as it seems.
If you don't quote the command substitution, its result undergoes word splitting and the \\
is seen as a separate element to loop over, that's why it gets its own line.
To just get the parts you want, you can use
$ grep -on '\\label{[^}]*}' test.tex
3:\label{r58}
10:\label{r59}
12:\label{r60}
19:\label{r61}
-o
to just retain the match, and the regex matches the braces after \label
as well.
Upvotes: 1