Skip to main content
replaced http://unix.stackexchange.com/ with https://unix.stackexchange.com/
Source Link

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linuxHow to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file. This code assumes that your file names don't contain : or newlines; if they might, things get complicated, and you'd better either rely on GNU grep's -Z optionrely on GNU grep's -Z option or process the files individually:

find "$path" -type f -exec sh -c 'for x; do grep -n "$0" <"$x" | awk -v fn="$x" -F: 'print fn ":" $1'; done' "$pattern" {} +

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file. This code assumes that your file names don't contain : or newlines; if they might, things get complicated, and you'd better either rely on GNU grep's -Z option or process the files individually:

find "$path" -type f -exec sh -c 'for x; do grep -n "$0" <"$x" | awk -v fn="$x" -F: 'print fn ":" $1'; done' "$pattern" {} +

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file. This code assumes that your file names don't contain : or newlines; if they might, things get complicated, and you'd better either rely on GNU grep's -Z option or process the files individually:

find "$path" -type f -exec sh -c 'for x; do grep -n "$0" <"$x" | awk -v fn="$x" -F: 'print fn ":" $1'; done' "$pattern" {} +
show a way to deal with : or newlines in file names
Source Link
Gilles 'SO- stop being evil'
  • 865.5k
  • 205
  • 1.8k
  • 2.3k

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file. This code assumes that your file names don't contain : or newlines; if they might, things get complicated, and you'd better either rely on GNU grep's -Z option or process the files individually:

find "$path" -type f -exec sh -c 'for x; do grep -n "$0" <"$x" | awk -v fn="$x" -F: 'print fn ":" $1'; done' "$pattern" {} +

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file.

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file. This code assumes that your file names don't contain : or newlines; if they might, things get complicated, and you'd better either rely on GNU grep's -Z option or process the files individually:

find "$path" -type f -exec sh -c 'for x; do grep -n "$0" <"$x" | awk -v fn="$x" -F: 'print fn ":" $1'; done' "$pattern" {} +
Source Link
Gilles 'SO- stop being evil'
  • 865.5k
  • 205
  • 1.8k
  • 2.3k

For the first part, note that xargs only works if there are no whitespace characters or \'" in your file names. See How to search for a word in entire content of a directory in linux for an explanation and an alternative.

Also, always put double quotes around variable substitutions: "$path". Without the double quotes, the shell expands whitespace and wildcards in the value of $path, so using it unquoted breaks if you have whitespace or wildcards in that file name. The same goes for $pattern (just for laughs, try leaving the quotes out and searching for h* in a directory containing files called hi and hello).

If your version of grep has the -r option to traverse directories recursively, you don't need find here. The -r option is present on Linux, FreeBSD, Mac OS X and Cygwin among others. Otherwise:

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

I fixed your awk call above, as well, so that it prints only the file name and the line numbers. I also pass the -H option to grep, to ensure that it always prints the file name, even if there happens to be a single file.