2

を使用してすべてのファイルの名前を変更しようとしてfindいましたが、これを実行した後...

find . -name '*tablet*' -exec sh -c "new=$(echo {} | sed 's/tablet/mobile/') && mv {} $new" \;

私のファイルがなくなって、それをecho$new の値に変更し、常に最初のファイルの名前を保持していることがわかったので、基本的にすべてのファイルの名前を同じ名前に変更しました

$ find . -name '*tablet*' -exec sh -c "new=$(echo {} | sed 's/tablet/mobile/') && echo $new" \;
_prev_page.tablet.erb
_prev_page.tablet.erb
_prev_page.tablet.erb
_prev_page.tablet.erb
_prev_page.tablet.erb
_prev_page.tablet.erb
_prev_page.tablet.erb

にも変更しようとしましたがexport new=...、同じ結果です

の値が変わらないのはなぜnewですか?

4

1 に答える 1

2

私が信じている問題は、コマンド置換がbashによって一度展開され、findが各呼び出しで結果を使用することです。理由が間違っているかもしれません。

たとえば、シェルスクリプトを書き出す前に同様のものがある場合

#! /bin/bash
old="$1"
new="${1/tablet/mobile}"
if [[ "${old}" != "${new}" ]]; then
    mv "${old}" "${new}"
fi

ファイルの名前を変更する処理を行い、find コマンドからそのスクリプトを呼び出すことができます

find . -name "*tablet*" -exec /path/to/script '{}' \;

物事を整理するのがはるかに簡単になります。

編集:

引用符をいじった後、コマンドをカプセル化する二重引用符を単一引用符に変更することで、これを整理できます。そのまま $() はシェルコマンドによって展開されます。以下のように実行された場合、コマンド置換は、exec によって呼び出されたシェルによって実行されます。

find . -name "*tablet*" -exec sh -c 'new=$( echo {} | sed "s/tablet/mobile/" ) && mv {} $new' \;

SO 問題は、コマンド置換が展開されるときに行うことです。単一引用符で囲むことにより、sh の呼び出しごとに展開を強制します。

于 2013-01-15T19:14:47.607 に答える