web-dev-qa-db-ja.com

`mv`でファイル名に改行を追加する

これは深刻な質問です。awkスクリプトをいくつかテストしましたが、名前に改行が含まれているファイルが必要です。


mvを使用してファイル名に改行を追加することはできますか?

私は今、これをtouchで行うことができます:

touch "foo
bar"

タッチで、コピーと貼り付けごとに改行文字を追加しました。でも書きませんfooReturnシェルのbar

ファイル名を改行するためにファイルの名前を変更するにはどうすればよいですか?


2015年6月28日編集、午後7時8分

使用できるzshに改行を追加するには、 Alt+Return

11
A.B.

(ファイル名に奇妙な文字を含めることは)悪い考えですが、あなたはそうすることができます

_ 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)expanded引数の配列を介して(シェルによって)与えられることを理解してください:引数の展開とグロビングは、起動するシェルの責任です。

また、小さな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_など)を使用してください

22

Bashを使用する場合、このコマンドは機能するはずです。

mv a $'b\nc'
19
favadi

私はあなたが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
6
kos

この問題の1つの側面は、実際にはawkに関するものではなく、シェルについてのほんの少しです。問題は、標準の標準ttyでは、ほとんどの場合、カーネルのtty規律が入力をバッファリングしている-それを画面にエコーするだけで、他の場所にはない-バックスペースなどを効率的に処理できるようにするためである。

ただし、Returnキーを押すか、改行を入力すると、バッファリングされたすべてのデータが読み取りアプリケーション(通常はシェル)に一度にプッシュされます。ぶら下がり引用符を入力した後に$PS2を監視すると、これを確認できます。シェルが$PS2を出力するのは、入力の一部のブロックを読み取っただけで、まだ完了していないためです。

したがって、便宜上、必要なのは、\newlineをターミナルバッファーに送信して、他のすべての入力をすぐにプッシュする必要がない方法です。これを行うための標準的な方法は、キーシーケンスCTRL+Vを使用することです。これは、端末の次の入力文字のquotesです。実行CTRL+V次にCTRL+J-後者は通常、リテラル\newlineを入力する方法であるためです。シェルがまだ入力を読み取っていないため、$PS2が表示されない場合でも機能していることがわかります。

ただし、それがdoesである場合、以前の入力を読み取りますCTRL+Vは、シェルではまったく違いがないことに注意してください。 。改行をシェルクォートして、それに意味のあることをしたいと思うでしょう。

ちなみに、CTRL+Vは他の方法でも便利に適用できます。たとえば、ESCを書く方法は"$(printf \\33)"だけではありません文字をシェルスクリプトに挿入します。これは最も単純なものでもありません。この方法で最初にエスケープするだけで、入力ドライバーが解釈することなく、キーボードが送信する任意の文字を文字どおりに入力できます。

シェルが何も完了しようとせずに、コマンドラインで<tab>を使用することがよくあります。補完を行うシェルは通常、stty eol \tと同義の方法で<tab>を構成するため、補完システムを機能させるために、慣れていない環境でもCTRL+Vが機能します。

5
mikeserv