디렉토리에는 여러 개의 PNG와 텍스트 파일이 있습니다. PNG 이름은 와 같은 UPC 바코드의 이름을 따서 지정됩니다. 052100029962.png
각 줄에 다음과 같이 제품 이름과 병합된 UPC 코드가 포함된 052100045535.png
텍스트 파일이 있습니다 .upcs.txt
...
052100029962mccormickpepper
052100045535mccormickonesheet
...
*.png*
텍스트 파일의 문자열과 일치하는 현재 파일 이름을 사용하여 UPC 번호 없이 각 파일의 이름을 제품 이름으로 바꾸고 싶습니다 . 052100029962.png
그래서 mccormickkeeper.png
. 아래의 다양한 방법을 시도했지만 성공하지 못했습니다.
for f in $(find . -iname "*.png"); do
while read -r line; do
if [[ "$f" == *"$line"* ]]; then ## also tried =~
cp "$f" "$line";
fi
done < upcs.txt
done
"다양성"이란 작업 순서를 바꾸는 것입니다. 예를 들어 루프 while
앞에 루프를 넣거나 for
제품 이름만 포함하는 다른 텍스트 파일을 만들어 read
비교할 수도 있습니다. 후자의 경우 다음을 수행했습니다.
for f in $(find . -iname "*.png"); do
while read -r line; do
if [[ "$f" == *"$line"* ]]; do
while read -r line2; do
cp "$f" "$line2";
done < upcs_names_only.txt;
fi;
done < upcs.txt;
done
while
루프를 호출하기 전에 두 번째 루프를 배치해 보기도 했습니다 if
.
마지막으로, 공식이 정확하더라도 위의 루프는아니요.png
확장자를 유지하세요 . 이 문제를 해결하기 위해 수동으로 결과를 선택하고 .png
.
내가 뭘 잘못했나요? 누구든지 논리를 더 잘 이해하도록 도와줄 수 있나요?
답변1
한 줄에 두 개의 필드가 있는 파일의 경우 구분 기호를 사용해야 합니다. 여기에 sed
이 구분 기호를 삽입하면 결과가 한 줄씩 제공됩니다.mv
#!/bin/bash
while read -r oldname newname; do
[ -f "${oldname}.png" ] && echo mv -- "${oldname}.png" "${newname}.png"
done < <(sed 's/^[0-9]*/& /' upcs.txt)
echo
테스트 후 제거하세요. 물론 첫 번째 필드는 항상 일련의 숫자이고 두 번째 필드에는 공백이 없고 숫자로 시작하지 않는다고 가정합니다.
중복 대상 이름 확인과 같은 추가 작업이 필요한 경우 먼저 파일에서 이 작업을 수행할 수 있습니다. 또는 어떤 경우에도 기존 대상을 덮어쓰지 않으려는 경우 ( )를 mv
사용 하면 같은 이유로 사용자에게 입력하라는 메시지가 표시됩니다 .-n
--no-clobber
-i
--interactive
답변2
스크립트에서 $f var는 052100029962.png이며 upcs.txt의 어떤 줄과도 일치하지 않습니다.
052100029962.png doesn't match *052100029962mccormickpepper*
UPC 번호가 항상 12자이거나 제품 이름이 숫자로 시작하지 않는다고 가정하면 텍스트 파일 줄을 반복하고 정규식을 사용하여 줄을 분할한 다음 파일 이름 {$upc}.png를 검색하고 이름을 { $product_name} .png.
#!/bin/bash
while read -r line; do
if [[ $line =~ ([0-9]{12})(.*) ]]; then
upc="${BASH_REMATCH[1]}.png"
name="${BASH_REMATCH[2]}.png"
if [[ -f $upc ]]; then
if [[ ! -f $name ]]; then
cp "$upc" "$name"
else
echo "$name already exists"
fi
fi
fi
done < upcs.txt
답변3
이를 수행하는 한 가지 방법은 다음과 같습니다. 그러나 이는 현재 디렉터리의 파일만 살펴보고 하위 디렉터리로 재귀적으로 이동하지 않는다는 점에 유의하세요.
while IFS= read -r l <&3
do
barcode=${l%%[!0-9]*}
value=${l#"$barcode"}
[ -f "$barcode.png" ] && \
printf '%s.png ' "$barcode" "$value"
done 3< upcs.txt | xargs -rn 2 -t cp -pdf --