`$0`을 대체하면서 이전 값을 저장하려면 어떻게 해야 합니까?

`$0`을 대체하면서 이전 값을 저장하려면 어떻게 해야 합니까?

"m"으로 시작하는 모든 파일의 이름을 첫 번째 문자(또는 이 경우 "m")를 제외하고 동일한 이름으로 바꾸려고 합니다.

내 전략은 다음과 같습니다.

  1. 모든 파일을 나열합니다.ls
  2. 내가 원하는 항목을 필터링하고egrep
  3. awk예를 들어 다음 과 같이 공백으로 구분하여 원하는 문자열 옆에 원하지 않는 문자열을 생성합니다.mfoo foo
  4. 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실제로 이름 바꾸기를 수행하려면 플래그를 제거하세요.

관련 정보