나는 Linux를 처음 접했지만 sed
새로운 awk
아이디어에 도전하는 것을 꺼리지 않습니다. 즉, 모든 파일에서 a를 추가하거나 제거하는 등의 일반적인 이벤트를 사용 rename
하고 sed
처리하는 목적과 방법을 이해합니다 $date
. _1234
그런데 파일 형식 외에는 서로 관계가 없는 100개의 파일 이름을 바꾸는 방법을 알고 싶습니다.
이름 바꾸기 예:
- 이전 이름인 alpha.ai가 omega.ai로 이름이 변경되었습니다.
- 이전 이름인 Pie32.ai가 apple.ai로 변경되었습니다.
- 이전 이름은 xmas.ai이고 이름은 santa.ai로 변경되었습니다.
처음에는 bash 스크립트를 사용하여 모든 이름을 .csv 파일로 추출하고 이를 A열에 배치했습니다. BI 열에 새 이름을 씁니다. 이제 일반적인 이벤트가 발생하지 않는데 sed
이를 수행하려면 어떻게 그런 내용을 작성해야 할까요?
#!/bin/bash
for i in *.ai
do
mv $i $(echo $i | sed "a1,b1")
done
답변1
다음과 같은 파일이 있는 경우:
old_name1, new_name1
old_name2, new_name2
old_name3, new_name3
더러운 작은 트릭을 할 수 있습니다.
sed 's/^/mv -vi "/;s/, /" "/;s/$/";/' < names.csv | bash -
sed 명령(세미콜론으로 구분)은 다음을 수행합니다( s
대체를 위해 /
구분 기호로 다른 문자를 사용해도 좋고 @
자주 사용됩니다).
s/^/mv -vi "/
mv -vi "
-각 줄의 시작 부분에 추가합니다(^
줄의 시작 부분).s/, /" "/
- 쉼표 다음에 공백이 오는 것을" "
; 로 바꾸십시오.s/$/";/
- 모든 줄에 큰따옴표를 추가합니다($
줄의 끝을 나타냄).
따라서 출력은 sed
다음과 같습니다.
mv -vi "old_name1" "new_name1"
mv -vi "old_name2" "new_name2"
mv -vi "old_name3" "new_name3"
처형 될 예정입니다 bash
. 파일 이름 주위의 따옴표는 필수가 아니며 단지 파일 이름에서 가능한 모든 공백을 보호할 뿐입니다(그러나 쉼표 뒤의 공백은 구분 기호로 사용되므로 확실히 도움이 되지 않습니다). 수행 중인 작업(무언가 잘못되면 무슨 일이 일어나고 있는지 알 수 있음)을 보여주는 지침을 통해 -v
이미 존재하는 파일을 덮어쓸지 묻는 메시지가 표시됩니다.mv
-i
답변2
스크립트에 몇 가지 참조 문제가 있습니다. 특수 문자(공백, \[?*-
.
** 변수 대체 및 명령 대체 "$i"
에는 항상 큰따옴표를 사용하십시오 "$(sed …)".
. 큰따옴표가 없으면 변수 값은 공백으로 구분된 와일드카드 패턴 목록으로 해석되며 각 패턴은 일치하는 파일 이름 목록으로 대체됩니다(일치 항목이 없으면 패턴은 변경되지 않은 상태로 유지됩니다).
또한 파일 이름이 로 시작하면 에 -
의해 옵션으로 해석되며 mv
옵션으로 해석될 수도 있습니다 echo
. 먼저 전달하면 --
명령에 더 이상 옵션이 없음을 알립니다.
for i in *.ai; do
mv -- "$i" "$(printf '%s\n' "$i" | sed 's,a1,b1,')"
done
sed
(이것은 여전히 파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.) (또한 매개변수를 귀하가 의도한 대로 수정했습니다 .)
파일 이름 목록이 따옴표 없이 단순히 쉼표로 구분된 경우 쉘 스크립트를 사용하여 구문 분석할 수 있습니다. 이는 파일 이름에 쉼표나 개행 문자가 없다고 가정합니다.
while IFS=, read -r from to junk; do
mv -- "$from" "$to"
done <"$files_to_rename.csv"
입력 파일이 참조할 수 있는 CSV 파일인 경우 실제 CSV 파서를 사용하세요. 직접 실행하려고 하지 마세요. 바라보다csv 파일을 처리하는 강력한 명령줄 도구가 있습니까?예를 들어 Python(표준 입력에서 CSV 사용)은 다음과 같습니다.
import csv, os, sys
for line in csv.reader(sys.stdin):
(source, dest) = line
os.rename(source, dest)
답변3
파일에 흥미로운 문자( '
, "
, \
, $
)가 있으면 파일을 반복하여 bash 배열로 읽을 수 있습니다.
while IFS=, read -r -a arr; do mv "${arr[@]}"; done <files.csv
답변4
이런 종류의 문제에 직면했을 때 나는 보통 수동 sed/bash 트릭을 사용합니다.
- csv 파일을 읽고 "mv file1 file2" 형식의 줄을 쓰는 편집기 매크로나 어리석은 작은 프로그램을 작성해야 합니다.
- 그런 다음 스크립트(또는 매크로)를 실행하고 출력을 run-my-cmds.sh에 저장합니다.
- run-my-cmds.sh를 시각적으로 검사하여 올바른지 확인하세요.
- bash는 내 cmds.sh를 실행합니다.