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.json
foo
path/to/foo.json
foo.json
find
-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
).