`mv`를 사용하여 파일 이름에 개행을 추가하십시오


11

심각한 질문입니다. 일부 awk스크립트를 테스트 하고 이름에 줄 바꿈이있는 파일이 필요합니다.


?를 사용하여 파일 이름에 줄 바꿈을 추가 할 수 mv있습니까?

나는 지금 이것을 할 수있다 touch:

touch "foo
bar"

터치로 복사 및 붙여 넣기마다 줄 바꿈 문자를 추가했습니다. 그러나 나는 fooReturnbar내 껍질에 쓸 수 없다 .

파일 이름에 줄 바꿈을하기 위해 파일 이름을 바꾸려면 어떻게해야합니까?


2015/06/28 편집; 오후 7:08

zsh사용할 수 있는 줄 바꿈을 추가하려면 Alt+Return


2
왜 물어? 친구에게 농담이나 속임수를 쓰고 있습니까?
Basile Starynkevitch 2016 년

2
질문을 제거하지 마십시오. 유용합니다. 그러나 실제로 파일 이름에 줄 바꿈을 최대한 피하십시오.
Basile Starynkevitch 2016 년

2
무엇을 하는가와 mv다른 생각을 touch하는가? 같은 것을 시도 했습니까?
케빈

2
글쎄, 당신은 mv쉽게 복사하여 명령에 붙여 넣을 수 있습니다 touch.
케빈

2
따라서 OP를보다 명확하게 공식화하도록 제안하겠습니다. 주어진 쉘 환경에서 에코 "a [return] b"와 같이 따옴표로 묶인 문자열 내에 줄 바꿈을 입력 할 수 없습니다.
dan

답변:


22

파일 이름에 이상한 문자가있는 것은 좋지 않은 생각이지만 할 수 있습니다.

 mv somefile.txt "foo
 bar"

( mv somefile.txt "$(printf "foo\nbar")"또는 할 수도 있습니다 mv somefile.txt foo$'\n'bar... 세부 사항은 쉘에 따라 다릅니다. 사용하고 있습니다 zsh)

globbing 에 대해 자세히 읽어보십시오 ( 예 : glob (7)) . 세부 사항은 쉘마다 다를 수 있습니다. 그러나이 이해 /bin/mv 를 통해, (쉘에서) 주어진 에서 execve (2) , 확장 인수의 배열 : 인수 확장과 글 로빙은 호출 쉘의 책임입니다.

작은 C 프로그램을 코딩하여 동일한 작업을 수행 할 수도 있습니다.

#include <stdio.h>
#include <stdlib.h>
int main() {
  if (rename ("somefile.txt", "foo\nbar")) {
     perror("rename somefile.txt");
     exit(EXIT_FAILURE);
  };
  return 0;
}

에 위의 프로그램을 저장 foo.c하고 컴파일 gcc -Wall foo.c -o foo 한 다음 실행하십시오../foo

마찬가지로 Perl, Ruby, Python, Ocaml 등에서 비슷한 스크립트를 코딩 할 수 있습니다.

그러나 그것은 나쁜 생각입니다. 파일 이름에 줄 바꿈을 피하십시오 (사용자를 혼란스럽게하고 많은 스크립트를 손상시킬 수 있음).

실제로 파일 경로에 강조되지 않은 문자, 숫자 및 +-/._% 문자 ( /디렉토리 구분자가있는) 만 사용하는 것이 좋습니다 . "숨겨진"파일 (로 시작 .)은주의해서 사용해야합니다. 파일 이름에 어떤 종류의 공간을 사용하는 것은 실수라고 생각합니다. 대신 밑줄을 사용하여 (예를 들어 foo/bar_bee1.txt) 또는 마이너스 (예 foo/bar-bee1.txt)


예, 줄 바꿈 문자를 복사하여 붙여 넣을 수는 있지만 복사하여 붙여 넣지 않고 어떻게 할 수 있습니까?
AB

4
여기에 사본이나 붙여 넣기가 없습니다. 뒤에 개행 문자가 foo있습니다.
dan

그러나 그것은 또한 복사하여 붙여 넣기를 작동합니다
kos

1
OP가 언급 한 것처럼 일반적인 파일에는 좋지 않지만 테스트 사례는 좋습니다.
artdanil

5
@그리고 ,보다 더 해가 될 것입니다 -(첫 번째 위치에서 같은) 나 %. 이러한 모든 권장 사항은 주로 일부 응용 프로그램의 버그를 해결하기위한 것입니다 (OS 관점에서 유효한 파일 이름을 손상시킵니다). 사람들에게 버그를 고치기보다는 그러한 캐릭터를 사용하지 말 것을 요구하는 것이 뒤로 느낀다.
Stéphane Chazelas 2016 년


6

mv경고가 있음에도 불구하고 해결책 을 요청한 것을 알고 있습니다 rename(Perl 패키지로).

~/tmp$ touch foo
~/tmp$ rename 's/$/\nbar/' foo
Unsuccessful stat on filename containing newline at /usr/share/perl5/File/Rename.pm line 69.
~/tmp$ ls
foo?bar

rename매우 좋은 아이디어 주셔서 감사합니다 . +1
AB

5

이 문제의 한 측면은 실제로 awk셸에 관한 것이 아니라 약간에 관한 것입니다. 문제는 표준의 표준 tty에서 대부분의 시간 동안 커널의 tty 규율이 입력을 버퍼링하는 것입니다-입력을 화면과 다른 곳으로 에코하는 것만으로 백 스페이스와 같은 것을 효율적으로 처리 할 수 ​​있습니다.

그러나 return 키를 누르거나 줄 바꿈을 입력하면 버퍼링 된 모든 데이터가 한 번에 읽기 응용 프로그램 (보통 셸)으로 푸시됩니다. $PS2매달린 따옴표를 입력 한 후 감시하여이를 확인할 수 있습니다 . 쉘이 인쇄 할 때 $PS2입력 블록을 읽었을뿐 아직 확실하지 않기 때문입니다.

따라서 편의상 필요한 것은 \n다른 모든 입력을 즉시 푸시하지 않고도 ewline을 터미널 버퍼로 보내는 방법입니다 . 이를위한 표준 방법은 키 시퀀스 를 사용하여 터미널에 다음 입력 문자 CTRL+V인용 하는 것입니다. 수행 CTRL+VCTRL+J- 후자는 문자를 입력하는 방법을 일반적이기 때문에 \newline을. $PS2쉘이 여전히 입력을 읽지 않았기 때문에 보이지 않을 때 작동한다는 것을 알게 될 것 입니다.

참고하지만 그것이이 때 않는 입력하여 이전 읽었 CTRL+V전혀 쉘에 대한 차이를하지 것이다 - 전용 회선 훈련을 위해 그것을 인용하고있다. 개행 문자를 따옴표로 묶고 의미있는 작업을 수행하고 싶을 것이다.

그건 그렇고, CTRL+V다른 방법으로 유용하게 적용 할 수 있습니다-예를 들어 문자를 쉘 스크립트 "$(printf \\33)"에 쓰는 유일한 방법 ESC은 아니며 가장 단순하지도 않습니다. 입력 드라이버가 먼저이 방법으로 키보드를 이스케이프 처리하면 키보드가 전송하는 문자를 문자 그대로 입력 할 수 있습니다.

쉘이 아무것도 시도하지 않고 명령 행에서 <tab>을 자주 사용하고 싶습니다. 완료를 수행하는 쉘은 일반적으로 <tab>을 동의어와 같이 구성 stty eol \t하여 완료 시스템이 작동하도록 CTRL+V하므로 익숙하지 않은 환경에서도 작동합니다.


2
'Ctrl + V'를 언급 해 주셔서 감사합니다. 나는 그것에 대한 답변을 게시하려고했고 당신의 설명을 보았습니다.
artdanil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.