ファイルのリストがあります
-rw-rw-r-- 1 t t 24813 Oct 23 2002 fig8_21.gif
-rw-rw-r-- 1 t t 2259 Oct 23 2002 fig8_21t.gif
-rw-rw-r-- 1 t t 35331 Oct 23 2002 fig8_23.gif
-rw-rw-r-- 1 t t 2610 Oct 23 2002 fig8_23t.gif
-rw-rw-r-- 1 t t 19970 Oct 23 2002 fig8_24.gif
-rw-rw-r-- 1 t t 2019 Oct 23 2002 fig8_24t.gif
-rw-rw-r-- 1 t t 54623 Oct 23 2002 fig8_3.gif
-rw-rw-r-- 1 t t 3657 Oct 23 2002 fig8_3t.gif
-rw-rw-r-- 1 t t 35861 Oct 23 2002 fig8_4.gif
-rw-rw-r-- 1 t t 2344 Oct 23 2002 fig8_4t.gif
たとえば、コピーして上書きを<...>t.gif
使用して上書きしたいと思います。<...>.gif
fig8_4.gif
fig8_4t.gif
私は<...>t.gif
これらのファイルを見つけることから始めますfind . -regex ".*t\.gif"
。次に、ファイル名の削除を使用したいのですが、basename
次の警告が表示されるのはなぜですか?
$ find . -regex ".*t\.gif" -execdir basename {} \;
find: The relative path `~/program_files/internet/SSH_tunneling/' is included in the PATH environment variable, which is insecure in combination with the -execdir action of find. Please remove that entry from $PATH
$ find . -regex ".*t\.gif" | xargs basename
basename: extra operand ‘./f10_1t.gif’
ミッションをどのように進めますか?
使用してはいけませんかfind
?
答え1
はい、可能です。 1つのアプローチは次のとおりです。
cd /den/of/gifs && \
for f in ./*t.gif; do
mv -- "${f%%t.gif}.gif" "$f"
done
最も長い一致文字列を削除するための${var%%pattern}
標準/POSIX構文。sh
模様年末から始まります$var
。
答え2
より小さく高速にするには、次のものを使用できますparallel
。
parallel mv {} {.}t.gif :::: <(find . -regex '.+[0-9].gif')
after式は::::
パラメータを提供しますparallel
。その後、このパラメータを使用してください{}
。{.}
ファイル拡張子のないパラメータを示します。そのため、この例で{}
は がないファイルのファイル名になります。たとえば。t
fig8_4.gif
{.}
fig8_4
答え3
find
sum を引き続き使用するには、basename
次のようにします。
find . -name "*.gif" ! -name "*t.gif" -execdir sh -c '
cp -- "$0" "$(basename "$0" .gif)t.gif"' {} \;
パフォーマンスとリソースの観点から見ると、これは最善の選択ではありません。
答え4
あなたのエラーについて:
find: 相対パス '~/program_files/internet/SSH_tunneling/' は PATH 環境変数に含まれており、 find の -execdir 操作で使用するのは安全ではありません。 $PATH からこのエントリを削除します。
あなた~/program_files/internet/SSH_tunneling/
は$PATH
文字通り~
。もちろんいいえあなたの意味メインディレクトリ。代わりに、次の意味があります。相対パス ~/program_files/internet/SSH_tunneling/
つまり、現在のディレクトリ内のディレクトリ内にありますSSH_tunneling
。internet
program_files
~
-execdir
コマンドを実行したいディレクトリに$PATH
移動する相対ディレクトリを好まないでください。chdir()
たとえば、ディレクトリツリーから降順に降りている間にディレクトリも含むfind
ファイルgif
が見つかっている場合は、最終的に実行できます。./some-dir
~
./some-dir/~/program_files/internet/SSH_tunneling/basename
それ basename
。
以下があるかもしれません。
PATH="~/program_files/internet/SSH_tunneling/"
あなたの場合は、次のようにする~/.bash*
必要があります。
PATH=~/program_files/internet/SSH_tunneling/
または
PATH="$HOME/program_files/internet/SSH_tunneling"
$ find . -regex ".*t\.gif" | xargs basename basename: extra operand ‘./f10_1t.gif’
xargs
basename
できるだけ多くのパラメータを使用して実行されます。basename
最大2つのパラメータが必要です。最初のパラメータはパスで、2番目のパラメータはモードです。したがって、あなたの命令は意味がありません。
また、デフォルトxargs
では、find
リストは入力時にスペース(ロケールや実装に応じてスペース、タブなどが可能)と改行(すべてファイル名に表示される場合があります)に区切る必要があります。そして引用符は特別に扱われます。これはフォーマット出力プロセスではありませんfind
。
find
次のように出力されます。
./path/to/picture from "The End of the World".gif
これは、xargs
の3つの異なるパラメータとして理解されます。予想される形式ではパターンが出力されません。ここでは次のようになります。./path/to/picture
from
The End of the World.gif
find
xargs
./path/to/picture\ from\ \"The\ End\ of\ the\ World\".gif
または
'./path/to/picture from "The End of the World".gif'
一部の実装では、スペース/改行+引用符の代わりにNUL区切りリストを処理するxargs
オプションがサポートされており、一部の実装にはその形式でファイル名を出力する述語があります(そうでない場合は代わりに使用できます)。-0
find
-print0
-exec printf '%s\0' {} +
だからこんな感じ:
find . -name "*t.gif" -print0 | xargs -r0 -I {} basename {} t.gif
これは全体的な目標に大きな助けにはなりません。代わりに、次のようなことをしたいと思います。
find . -name '*t.gif' -type f -exec sh -c '
for f do
cp "${f%t.gif}.gif" "$f"
done' sh {} +
または以下を使用してzsh
:
autoload zmv # if not already in ~/.zshrc
zmv -C '(**/)(*)t.gif(#qD.)' '$1$2.gif'