파일 세트의 이름을 각 파일에 있는 문자열로 바꿉니다.

파일 세트의 이름을 각 파일에 있는 문자열로 바꿉니다.

json 파일 세트가 있습니다. 각 파일에는 json 개체가 포함되어 있으며 모두 동일한 스키마를 갖습니다. 파일 이름을 json의 필드로 바꾸고 싶습니다. 어떻게 해야 하나요?

나는 이 해결책을 생각해 냈습니다.

find . -name '*.json' | xargs -i mv {} $(cat {} | jq '.billingAccountList[0]' | tr -d \").json

cat하지만 {}를 해석하려고 하기 때문에 작동하지 않습니다 . xargs가 설명할 수 있기를 바랍니다. 나에게 다음과 같은 오류가 발생합니다.

cat: {}: No such file or directory

답변1

루프를 사용하여 파일을 하나씩 처리합니다.

예를 들어 다음과 같습니다 while read.

find . -name '*.json' | while read fname; do
    newname=$(jq -r '.billingAccountList[0]' "${fname}").json
    mv "${fname}" "${newname}"
done

가능할 수도 있지만 다음 을 사용하여 for파일 이름의 공백에 더 민감합니다 .

for fname in $(find . -name '*.json'); do
    ... (same as above) ...

또한 파일을 다음 위치로 이동한다는 점에 유의하세요.현재의원래 경로가 제거되었으므로 디렉터리 구조를 유지하려면 다음을 수행하십시오.

find . -name '*.json' | while read fname; do
    fdir=$(dirname "${fname}")
    newname=$(jq -r '.billingAccountList[0]' "${fname}").json
    mv "${fname}" "${fdir}/${newname}"
done

고쳐 쓰다jq -r: @steeldriver가 제안한 대로 사용됩니다. 감사해요!

답변2

jq -r다음을 사용하여 원시(따옴표가 없는) 문자열을 출력 할 수 있어야 합니다.tr

또한 상위 디렉터리를 기준으로 파일 이름을 바꾸고(예를 들어 값이 .billingAccountList[0]이면 새 이름은 대신이어야 함 ) 구현에 다음이 있다고 가정합니다.path/to/file.jsonfoopath/to/foo.jsonfoo.jsonfind-execdir

그래서 나는 다음과 같은 것을 할 것입니다

find . -name '*.json' -execdir sh -c '
  echo mv -- "$1" "$(jq -r ".billingAccountList[0]" < "$1").json"
' find-sh {} \;

또는 (적어도 GNU의 경우 find) 더 효율적입니다.

find . -name '*.json' -execdir sh -c '
  for f; do echo mv "$f" "$(jq -r ".billingAccountList[0]" < "$f").json"; done
' find-sh {} +

echo올바른 일을 하고 있다는 확신이 들면 제거하세요.

답변3

zsh를 사용하면 zmv(더 나은 충돌 처리를 위해):

autoload zmv
zmv -n '(**/)*.json(#qD.)' '$1$(jq -r '.billingAccountList[0]' < $f).json

(행복하면 삭제 -n).

관련 정보