"$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을 유지합니다 . 그런 다음 이전 항목과 새 항목을 함께 넣어 보내려는 행을 가져온 다음 올바른 매개변수를 사용하여 호출하여 이름을 바꿉니다.$0gsubxargsmv

답변3

더 나은 전략은 rename명령을 사용하는 것입니다.

이 명령의 정확한 구문은 배포판마다 다릅니다. man특정 배포 버전에 대한 페이지를 참조하세요. 예를 들어 Perl 구현이 있는 Ubuntu에서는 rename정규식을 사용할 수 있습니다.

rename -nono 's/^m//' m*

참고: -nono실제로 이름 바꾸기를 수행하려면 이 플래그를 제거하십시오.

관련 정보