Search code examples
regexstringfindxargs

How do I grep a string using the previous output for my next argument?


There is a string located within a file that starts with 4bceb and is 32 characters long. To find it I tried the following

Input:

find / -type f 2>/dev/null | xargs grep "4bceb\w{27}" 2>/dev/null

after entering the command it seems like the script is awaiting some additional command.


Solution

  • Your command seems alright in principle, i.e. it should correctly execute the grep command for each file find returns. However, I don't believe your regular expression (respectively the way you call grep) is correct for what you want to achieve.

    First, in order to get your expression to work, you need to tell grep that you are using Perl syntax by specifying the -P flag.

    Second, your regexp will return the full lines that contain sequences starting with "4bceb" that are at least 32 characters long, but may be longer as well. If, for example your ./test.txt file contents were

    4bcebUUUUUUUUUUUUUUUUUUUUUUUU31
    4bcebVVVVVVVVVVVVVVVVVVVVVVVVV32
    4bcebWWWWWWWWWWWWWWWWWWWWWWWWWW33
    sometext4bcebYYYYYYYYYYYYYYYYYYYYYYYYY32somemoretext
    othertext 4bcebZZZZZZZZZZZZZZZZZZZZZZZZZ32 evenmoretext
    

    your output would include all lines except the first one (in which the sequence is shorter than 32 characters). If you actually want to limit your results to lines that just contain sequences that are exactly 32 characters long, you can use the -w flag (for word-regexp) with grep, which would only return lines 2 and 5 in the above example.

    Third, if you only want the match but not the surrounding text, the grep flag -o will do exactly this.

    And finally, you don't need to pipe the find output into xargs, as grep can directly do what you want:

    grep -rnPow / -e "4bceb\w{27}"
    

    will recursively (-r) scan all files starting from / and return just the ones that contain matching words, along with the matches (as well as the line numbers they were found in, as result of the flag -n):

    ./test.txt:2:4bcebVVVVVVVVVVVVVVVVVVVVVVVVV32
    ./test.txt:5:4bcebZZZZZZZZZZZZZZZZZZZZZZZZZ32