web-dev-qa-db-ja.com

このxargsコマンドが機能しないのはなぜですか?

私はすべての.sh拡張子を削除したかったので、これを行いました:

ls *.sh | xargs -I {} mv {} `basename {} .sh`

ただし、機能しません。basenameが変更されていないファイル名を返すように動作します。

なぜそれはそのように振る舞うのですか?

たとえば、これは動作します:

ls *.sh | xargs -I {} echo `basename {}.jpg .jpg`;

[〜#〜]編集[〜#〜]

解決策:単一引用符は`basename ...`コマンドが実行される前のシェルによる評価。

ls *.sh | xargs -I {}  sh -c 'mv {} `basename {} .sh`'
14
majkinetor

パイプラインが実行される前にbasenameコマンドが実行されるためです。これを機能させるには、basenameを実行するxargsが必要です。これをsh -cで実行できます。例:

ls *.sh | xargs -L1 sh -c 'basename $1 .sh' dummy

ノート:

  • xargsにファイル名を挿入する場所を指定しないと、コマンドラインの最後に追加されます。
  • -L1スイッチまたは同等のスイッチを使用する必要があるため、xargsshに1つの引数のみを渡します。
  • lsの出力を使用すると 望ましくない効果 が発生する可能性があります。

編集する

TechZillaに感謝して、非推奨のオプションを削除しました

12
Thor

私はあなたの質問がわからない、あなたは実際にあなたの最初の行が機能しない理由を実際に尋ねていますか?または、すべての.shファイルの名前を変更する適切な方法を探していますか?

それが最もクリーンな方法だとすると、xargsの前にコマンドオプションを準備することを好みます。 .shファイル拡張子を削除するために、私はこのアプローチをよく考えます、

 find -maxdepth 1 -type f -iname '*.sh'  | sed 'p;s_.sh$__' | xargs -L2 mv
4
J. M. Becker