"m"으로 시작하는 모든 파일의 이름을 첫 번째 문자(또는 이 경우 "m")를 제외하고 동일한 이름으로 바꾸려고 합니다.
내 전략은 다음과 같습니다.
- 모든 파일을 나열합니다.
ls
- 내가 원하는 항목을 필터링하고
egrep
awk
예를 들어 다음 과 같이 공백으로 구분하여 원하는 문자열 옆에 원하지 않는 문자열을 생성합니다.mfoo foo
xargs
에 공급mv mfoo foo
몇 가지 질문:
- 이것이 좋은 전략인가?
- 더 좋은 것은 무엇입니까?
3단계에서 막혔습니다. 아래는 문제에 접근한 방법입니다.
저는 다음 디렉토리에서 작업하고 있습니다.
$ find .
.
./cat
./mbar
./mbaz
./mfoo
1-2를 빠르게 얻을 수 있습니다.
$ ls | egrep '^m'
mbar
mbaz
mfoo
3단계는 더 어렵습니다. 나는 gsub
원하는 두 번째 문자열을 생성했지만 "공백으로 구분된 원래 값과 함께 붙이는" 방법을 잘 모르겠습니다.
$ ls | egrep '^m' | awk '{ gsub(/^./, ""); print }'
bar
baz
foo
4단계는 이해가 되지만 3단계를 어떻게 완료해야 할지 모르기 때문에 아직 완료할 수 없습니다. 다음은 이것이 어떻게 작동해야 한다고 생각하는지에 대한 한 가지 예입니다.
$ echo mfoo foo | xargs mv
$ find .
.
./cat
./foo
./mbar
./mbaz
거의 다 된 것 같아요. 이전 값을 저장하고 gsubed 값 옆에 인쇄하는 방법만 알아내면 됩니다. 다음과 같은 작은 예를 시도했지만 작동하지 않습니다.
$ echo mfoo | awk '
pipe quote> { old = $0 }
pipe quote> { new = gsub(/^./, "") }
pipe quote> { print $old " " $new }'
awk: illegal field $(mfoo), name "old"
input record number 1, file
source line number 4
$0
이전 값을 대체하고 저장하려면 어떻게 해야 합니까 ?- 이 오류가 발생하는 이유는 무엇입니까?
답변1
이는 전체 작업을 처리해야 합니다.
for file in m*; do mv "${file}" "${file#m}"; done
실행하기 전에 먼저 다음 사항을 확인하세요.
for file in m*; do echo mv "${file}" "${file#m}"; done
이는 m*
1단계와 2단계에 glob을 사용하고, 3단계에는 ${file#m}
(의 시작 부분에서 "m"을 제거함 ${file}
) 마지막으로 4단계에는 루프를 사용합니다.
AWK 질문에 답하려면 다음과 같이 할 수 있습니다.
echo mfoo | awk '{ print $0, substr($0, 2) }'
AWK 변수는 를 사용하지 않습니다 $
. 이는 단지 필드용입니다. 이것이 바로 오류가 발생하는 곳입니다. AWK는 $old
"값에 따라 번호가 매겨진 필드 값 old
"으로 이해합니다. 명령을 단일 블록에 배치하면 읽기도 더 쉽습니다(동일한 패턴을 가지고 있다고 가정). 스크립트를 수정하면
echo mfoo | awk '{ old = $0; gsub(/^./, ""); print old, $0 }'
답변2
ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -l -t mv
Posix-리-L
구현은 다음 과 같은 옵션을 통해 이루어집니다 xargs
.
ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -L 1 -t mv
ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); print x, $0 }' | xargs -L 1 -t mv
무엇을 기준으로나는 대답했다에 관한 이전 쿼리에 대한 xargs
학습 내용을 이 예에서 잘 활용할 수 있습니다.
귀하의 코드를 약간 수정했습니다 . func가 코드를 망칠 것이기 때문에 awk
원래 줄( $0
)을 유지합니다. gsub
그런 다음 이전 항목과 새 항목을 함께 모아 전송하려는 줄을 얻은 xargs
다음 mv
올바른 인수를 사용하여 호출하여 이름 바꾸기를 수행합니다.
답변3
더 나은 전략은 rename
명령을 사용하는 것입니다.
이 명령의 정확한 구문은 distro에 따라 다르므로 man
특정 distro 버전의 페이지를 참조하세요. 예를 들어 Perl이 구현된 Ubuntu에서는 rename
정규식을 사용할 수 있습니다.
rename -nono 's/^m//' m*
참고: -nono
실제로 이름 바꾸기를 수행하려면 플래그를 제거하세요.