file2
の内容をfile1
の内容と一致させたい場合は、cp file1 file2
を実行するだけで十分です。
ただし、file2
以外についてすべてを保持したい場合は、コンテンツ(所有者、権限、拡張属性、ACL)を除きます、ハードリンクなどの場合、cp
。*を実行したくありません。その場合は、file1
の内容をfile2
にプロップします。
次のようにしてください:
< file1 > file2
しかし、それは機能しません。 file2
は何も切り捨てられず、書き込まれません。しかしながら、
cat < file1 > file2
は動作します。
最初のバージョンが動かないのには驚きました。
2番目のバージョンはUUOCですか?リダイレクトを使用するだけで、コマンドを呼び出さずにこれを行う方法はありますか?
注:私は、UUOCが真のアンチパターンというよりも重要な点であることを知っています。
*tniles09が発見した のように、cp
は実際にはこの場合に機能します。
cat < file1 > file2
はUUOCではありません。古典的には、<
および>
は、システムレベルでのファイル記述子の重複に対応するリダイレクトを行います。ファイル記述子の複製自体は何もしません(まあ、>
リダイレクトはO_TRUNC
で開くため、正確に言えば、出力リダイレクトは出力ファイルを切り捨てます)。 <
>
の記号が混乱しないようにしてください。リダイレクトではデータは移動されません。ファイルの記述子が他のファイル記述子に割り当てられます。
この場合、file1
を開き、そのファイル記述子をファイル記述子0
(<file1
== 0<file1
)およびfile2
に割り当て、そのファイル記述子をファイルに割り当てます。記述子1
(>file2
== 1>file2
)。
これで2つのファイル記述子ができたので、2つのファイル間でデータをシャベル処理するプロセスが必要です。これがcat
の目的です。
他の人が指摘しているように、問題の動作はシェルに依存しているため、そうではありません。あなた(OP)が指摘したように、これは少し pedantic であり、多分 humorous? のトピックです。
ただし、GNU=システムでは、最初の前提で別のソリューションを使用できます:cp --no-preserve=all file1 file2
。これを試してみてください。記述された状況(たとえば、属性を変更せずにfile2
の内容を変更)は満たすと思います。
例:
$ ls -l
total 8
-rw-r--r-- 1 tniles sambashare 16 Dec 16 12:21 fezzik
-rw-r--r-- 1 tniles tniles 14 Dec 16 12:16 fred
$ cat *
Lookout, world!
Hello, world!
$ cp --no-preserve=all fred fezzik
$ ls -l
total 8
-rw-r--r-- 1 tniles sambashare 14 Dec 16 12:22 fezzik
-rw-r--r-- 1 tniles tniles 14 Dec 16 12:16 fred
$ cat *
Hello, world!
Hello, world!
[〜#〜] update [〜#〜]実際には、システムのcp
自体が属性を保持しているように見えますが、 -a
または-p
が指定されている。私はbashシェルとGNU coreutils。を使用しています。毎日新しいことを学んでいると思います...
ハードリンクとさまざまな権限を含むテスト結果(ワイルドカードによる):
$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete vagrant 39 Dec 16 20:35 file2
913965 -rwxrw---- 2 pete vagrant 39 Dec 16 20:35 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the original contents of file2
$ cp file1 file2
$ ls -li
total 12
913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1
913965 -rwxrw---- 2 pete vagrant 30 Dec 16 20:37 file2
913965 -rwxrw---- 2 pete vagrant 30 Dec 16 20:37 hardlinktofile2
$ cat file1
This is the contents of file1
$ cat file2
This is the contents of file1
$
zsh
、< file1 > file2
が機能するシェルでは、シェルはcat
を呼び出します。
リダイレクトのみで構成され、コマンドも割り当てもないコマンドラインの場合、リダイレクトが$NULLCMD
である場合を除き、zsh
は<
(デフォルトではcat
)を呼び出します。代わりに$READNULLCMD
(デフォルトではpager
)が呼び出されます。 (これは、zsh
がsh
またはcsh
エミュレーションに含まれていない限り、エミュレーションするシェルのように動作します)。
そう:
< file1 > file2
実際には同じです
cat < file1 > file2
そして
< file1
と同じです
pager < file1
< from > to
コマンドがないので機能しません。プロセスなし。シェルはファイルを開く/作成し、リダイレクトを調整します(つまり、これらのファイルを参照するファイル記述子は0および1:標準入力と標準出力として作成されます)。ただし、ループを実行して標準入力から読み取り、標準出力に書き込む処理はありません。
zsh
は、この「nullコマンド」の場合にユーザー設定可能なコマンドを代用することで、この機能を実現します。コマンドはコマンドラインに表示されませんが、まだ存在しています。プロセスが作成され、同じように動作します。 NULLCMD
がデフォルトでcat
であるため、zsh
が他の値に設定されていない限り、_< from > to
は実際にはNULLCMD
内の__meanscat < from > to
です。これは「暗黙の猫」コマンドです。
「猫の無用な使用」は、cat
がファイルから読み取られ、データを別のプロセスに送る媒介として使用されるときに発生します。そのプロセスのファイル記述子は、元のファイルに接続されているだけです。
cat
がシチュエーションから除去可能で、残りのコマンドが同じタスクを実行できる場合、それは役に立ちません。取り外し可能でない場合、それは役に立たないというわけではありません。
# useless, removable:
$ cat archive.tar | tar tf - # --> tar tf archive.tar
# not removable (in POSIX Shell):
$ cat > file
abc
[Ctrl-D]
# likewise:
STRING=$(cat file)
cat
、つまり置換可能は同じものではありません。たとえば、cat > file
の代わりに、vi file
を使用してファイルを作成できます。これは、cat
の削除としてはカウントされませんが、残っているものを使用して同じタスクを実行します。
cat
がパイプラインのonlyコマンドの場合、もちろん削除できません。残っているものを再配置しても、同等の処理は行われません。
一部のシェルスクリプターは、cat
を使用して、入力オペランドをコマンドラインの左側に近づけることができると考えています。ただし、リダイレクトはコマンドラインのどこにでも置くことができます。
# If you're so inclined:
# move source archive operand to the left without cat:
$ < archive.tar tar xf - > listing
すべての良い答えに加えて、simulating a cat
によってUUOCを回避できます。
awk 1 file1 > file2 # For line-oriented text, not binaries.
dd if=file1 of=file2 # Works for binary files, too.
# many more geeky ways.
これらのコマンドは、プレーンなcp
の場合のように、ファイルメタデータをコピーしません。
< file1 > file2
シェルに依存しているようです。zshでは機能しますが、bashでは機能しません。
編集:削除されたfalseステートメント
動作する場合は、修正しないでください。
私は使うだろう
cat < file1 > file2
セマンティクスのPCに汗を流さないでください。