"find"에서 jq로 여러 파일 파이프

"find"에서 jq로 여러 파일 파이프

프로젝트의 node_module 폴더에 있는 특정 노드 패키지의 모든 버전을 가져오려고 합니다.

package.json 파일이 여러 개 있고 "종속성": {"package-name"} 아래의 파일을 "grep"하고 싶습니다.

샘플 JSON 파일:

{
  "dependencies": {
    "some-package": "^1.1.1",
    "some-package": "^1.0.1",
    "the-package-i-am-looking-for": "1.2.3"
  },
  "devDependencies": {
    "some-package": "^1.7.3",
    "some-package": "^2.0.0"
  }
}

파일명과 라인을 알고 싶습니다. (그래서 grep)

따라서 이상적으로 출력은 다음과 같아야 합니다.

some-package/package.json: "the-package-i-am-looking-for": "1.2.3"
some-other-package/package.json: "the-package-i-am-looking-for": "2.3.4"

저는 유닉스 파이프를 처음 사용합니다. 이것이 내가 생각해낸 것입니다. 이것은 분명히 작동하지 않습니다

find . -name package.json | xargs cat | jq '.dependencies' | grep '"the-package-i-am-looking-for"'

당신의 도움을 주셔서 감사합니다

답변1

cat원본 파일의 이름은 파이프라인 다운스트림 부분에서 액세스할 수 없습니다 . 그 cat시점부터 파이프에 도달하는 모든 것은 하나 이상의 파일 내용으로 구성된 데이터입니다.

믿다당신이 찾고 있는 것은 다음과 같습니다:

find . -type f -name package.json \
    -exec jq -r --arg pkg 'the-package-i-am-looking-for' \
        '.dependencies | .[$pkg] // empty | [input_filename,$pkg,.] | @tsv' {} +

그러면 탭으로 구분된 세 가지 필드 목록이 출력됩니다.

  1. 패키지가 발견된 파일의 경로 이름입니다.
  2. 패키지 이름.
  3. 버전 문자열.

find명령 jq일괄jq발견된 경로 이름은 가능한 한 적은 수의 호출이 완료되도록 출력을 생성하는 데 사용됩니다 . {} +마지막에 있는 파일은 -exec수집된 파일 이름으로 대체됩니다.

jq호출은 입력 파일을 구문 분석하고, 값을 추출하고 .dependencies, 찾고 있는 패키지에 해당하는 키에 대한 버전 문자열을 가져와서 출력을 생성하고, 무언가가 발견되면 현재 파일 이름, 쿼리 중인 패키지 이름 및 version 탭으로 구분된 목록인 문자열 자체입니다 @tsv.

출력 형식은 필요에 맞게 수정할 수 있습니다. CSV 형식으로 출력되도록 @tsv변경할 수 있습니다 .@csv

현재 디렉터리와 디렉터리 이름에 제공된 파일 복사본의 예(형식 문제가 수정됨) dir:

$ tree
.
|-- dir
|   `-- package.json
`-- package.json

1 directory, 2 files
$ find . -type f -name package.json -exec jq -r --arg pkg 'the-package-i-am-looking-for' -e '.dependencies | .[$pkg] // empty | [input_filename,$pkg,.] | @tsv' {} +
./package.json  the-package-i-am-looking-for    1.2.3
./dir/package.json      the-package-i-am-looking-for    1.2.3

find과 사이에 파이프가 정말로 필요하다고 생각되면 xargs다음과 같은 이식 불가능한 코드를 사용할 수 있습니다.

find . -type f -name package.json -print0 |
xargs -0 \
    jq -r --arg pkg 'the-package-i-am-looking-for' \
        '.dependencies | .[$pkg] // empty | [input_filename,$pkg,.] | @tsv'

모든 것을 직접 수행하는 것에 비해 이런 방식으로 수행하면 얻을 수 있는 것이 없습니다 find.

관련 정보