grep으로 출력된 파일 이름 뒤에 공백을 추가하는 방법은 무엇입니까?

grep으로 출력된 파일 이름 뒤에 공백을 추가하는 방법은 무엇입니까?

나는 grep파일 내에서 일치하는 패턴을 검색하고 출력에서 ​​해당 파일 이름을 복사하는 데 사용합니다. 이 작업을 너무 자주 하다 보니 :결국 복사도 하게 될 것 같습니다. 그렇다면 첫 번째로 일치하는 절반 열이나 파일 이름이 끝나기 전에 두 개의 공백을 추가할 수 있습니까?

$ grep -Hrn -e "zorro" --color=always --exclude-dir=dir -I -F . | \
    cut -c 11- | awk '$0="\033[33;35m"$0' | tr -s '[:space:]'
doo.tex:1:zorro alper alper alper skfjsdlkfj dslfj dslkj

원하는 출력:

doo.tex  :1:zorro alper alper alper skfjsdlkfj dslfj dslkj
        ^
  <two space added>

답변1

그래도 내 첫 번째는 갔다

awk -F: -vOFS=: '{$1 = $1 "  "; print}'

그러나 나는 그것이 필요 이상으로 일이 많다고 생각합니다. 분열하고 대열에 다시 합류하는 것입니다.

이것대안은 매우 깔끔합니다

sed 's/:/  :/'

바꾸다첫 번째공백 2개와 콜론이 있는 콜론입니다.


콜론 대화가 포함된 파일 이름 관련:

GNU grep 매뉴얼 페이지를 읽어보십시오. -Z옵션 사용: "일반적으로 파일 이름 뒤에 오는 문자 대신 0바이트(ASCII NUL 문자)를 출력합니다."

그래서:

# .......v
grep -HrnZ -e "zorro" --color=always --exclude-dir=dir -I -F . | \
  perl -pe 's/\0/  :/'

답변2

"zorro"와 같은 패턴과 일치하는 텍스트가 포함된 파일 이름 목록만 필요하고 해당 파일 이름을 다른 프로그램에서 사용하려는 경우 다음과 같은 작업을 수행하여 파일 이름이 포함된 bash 배열을 만들 수 있습니다. 마우스를 사용하여 수동으로 복사하여 붙여넣는 작업을 많이 피하세요.

mapfile -d '' -t myfiles < <(grep -IFlZr zorro ./)

mapfilestdin에서 배열을 채우기 위한 bash 내장 명령입니다. 이 경우 표준 입력은 다음 grep과 같이 제공됩니다.프로세스 교체. with를 사용 하여 입력이 NUL 문자로 구분된다는 점을 알리고, NUL로 구분된 일치하는 파일 이름 목록을 출력하는 데 -d ''with를 사용 합니다 . 이는 다음과 같습니다.mapfile-Zgrep어느콜론, 공백, 줄 바꿈 및 셸 메타 문자를 포함하여 이름에 포함된 문자와 관계없이 파일 이름입니다.

를 사용하여 배열의 내용을 보거나 declare -p myfiles배열 요소를 다른 프로그램(예: printf '%s\'n' "${myfiles[@]}")에 대한 인수로 사용하거나 유사한 루프에서 사용할 수 있습니다 for f in "${myfiles[@]}"; do echo "$f" ; done.

참고: grep의 -l옵션은 첫 번째 일치 후에 종료되므로( option 과 동일 -m) 검색 문자열이 파일의 앞부분에 나타나는 파일에서 검색 속도가 빨라집니다. 패턴이 나타나지 않는 파일에서는 여전히 전체 파일을 읽어야 합니다.

그런데 이 옵션을 사용하는 이유가 -I바이너리 파일(예: TeX의 .pdf 또는 .dvi 출력)을 피하려는 경우 다음과 같이 find사용할 수 있습니다 grep -r.

mapfile -d '' -t myfiles < <(find . -type f -name '*.tex' -exec grep -lZF zorro {} +)

grep보다 더 복잡한 선택 기준이 필요한 경우 grep 대신 awk나 perl 등을 사용할 수 있습니다. 예를 들어, 파일의 3번째 줄에 "zorro"가 나타나는 파일 이름만 원하는 경우:

mapfile -d '' -t myfiles < <(find . -type f -name '*.tex' \
  -exec perl -n -e 'if ($. == 3) {
                      printf "%s\0", $ARGV if (/\Qzorro\E/);
                      close(ARGV);
                    }' {} +)

이것은 단순한 예일 뿐입니다. 표준을 생각하고 이를 Perl(또는 awk, Python 등) 스크립트로 작성할 수 있다면 이를 사용하여 선택적으로 배열을 채울 수 있습니다. 파일 이름을 표준 출력으로 인쇄하고 NUL 문자로 구분하는 한 모든 명령이나 길고 복잡한 명령 파이프라인을 사용할 수 있습니다.

참고: close(ARGV)파일 이름이 인쇄되는지 여부에 관계없이 현재 파일을 닫고 다음 파일(있는 경우)로 이동합니다. 즉, 파일에서 세 줄 이상을 읽을 필요가 없으므로 대용량 파일을 많이 검색하는 경우 훨씬 더 빠릅니다.

참고 2: \Qand는 grep \E과 유사하게 고정 문자열 검색을 수행하는 Perl의 방식입니다 -F. awk를 사용하면 이 index()기능을 사용하여 비슷한 작업을 수행할 수 있습니다.

관련 정보