2017-03-11 11 views
0

私は現在のディレクトリ内の一致するすべてのファイルの拡張子を変更します関数を記述しようとしています:ワイルドカードでargvを使用するにはどうすればよいですか?

function chext 
    if count $args -eq 2 > /dev/null 
    for f in (ls *$argv[1]) 
     mv (basename $f $argv[2]) (basename $f $argv[1]) 
    end 
    else 
    echo "Error: use the following syntax" 
    echo "chext oldext newext" 
    end 
end 

私もこの出力を得続ける:

(*master) λ chext markdown txt 
No matches for wildcard '*$argv[1]'. (Tip: empty matches are allowed in 'set', 'count', 'for'.) 
~/.config/fish/config.fish (line 1): ls *$argv[1] 
             ^
in command substitution 
     called on line 60 of file ~/.config/fish/config.fish 

in function 'chext' 
     called on standard input 
     with parameter list 'markdown txt' 

私は存在する必要があります知っています変数を補間し、*をワイルドカードとして保持する方法ですが、わかりません。私は(string join '*' $argv[1])を使ってみましたが、ワイルドカードを文字列に変換しました。

私はほとんど仕事にこれを手に入れた:それは私のファイルのすべてだったのエラーを与え、その後、私のすべてのファイルから拡張子を取り除いたが、新しいものを追加していない

function chext 
    if count $args -eq 2 > /dev/null 
    for f in (ls (string join * $argv[1])) 
     mv (basename $f $argv[2]) (basename $f $argv[1]) 
    end 
    else 
    echo "Error: use the following syntax" 
    echo "chext oldext newext" 
    end 
end 

結合した名前とファイル名が長すぎます。

UPDATE:

私は正しいls作業を取得する方法があると確信しているが、私はこれが正常に働いて取得しました:

if count $args -eq 2 > /dev/null 
    for f in (ls) 
     mv $f (string replace -r \.$argv[1]\$ .$argv[2] (basename $f)) 
    end 
    else 
    echo "Error: use the following syntax" 
    echo "chext oldext newext" 
    end 
end 

答えて

2

答えはメッセージである:

ワイルドカード '* $ argv [1]'には一致しません。 (ヒント:空のマッチは 'の'、 '設定'、 '数' は許可されています。)

for i in *argv[1] 

作品を意味することに

set -l expanded *argv[1] 

の場合がそうであるように何も一致しないglobで他のコマンドを起動しようとすると、fishは実行をスキップしてエラーを出力します。


この機能には多数の問題があり、1つずつ順番に解決できます。数$ argsを-eq 2>を/ dev/null

count場合

は "-eq 2" の引数を取りません。引数が与えられたときは常に0(つまりtrue)が返されるため、常にtrueになります。

あなたがしようとしたのはif test (count $args) -eq 2でした。また、作品(と私はより多くを好きに起こる)何

if set -q argv[2]

である(また、それは "引数V" ではなく、 "引数" です)。

でのfに対する

(LS *の$ ARGV [1])

lsの出力を使用しないでください。魚には魚のように多くの問題はありません(名前にスペース、タブ、改行があると壊れます)が、不要です(追加のプロセスを起動します)。問題 - ファイル名に改行があったときに改行されます。

ちょうどfor f in *$argv[1]を実行してください。これもあなたの質問をうまく解決します。

mv (basename $f $argv[2]) (basename $f $argv[1]) 

私はあなたがここで使用しているbasenameわからないんだけど、鉱山はちょうどサフィックスを削除します。あなたがchext .opus .oggをしたのであれば、これは個人的に

mv song.opus song 

に解決されます

mv (basename song.opus .ogg) (basename song.opus .opus) 

を実行するだろう、私はこのためstring replaceを使用すると思います。

mv $f (string replace -- $argv[1] $argv[2] $f) 

(のようなものは注意:拡張文字列の前に表示された場合、これは間違ったことをするだろう、例えばあなたが最初の「.OGGは、」だろう「f.ogg-banana.ogg」と呼ばれるファイルを持っていた場合あなたはこれに正規表現を使用したいと思うかもしれません:string replace -r -- "$argv[1]\$" $argv[2] $f

+0

うわー、これらの問題を通過するために時間を費やしてくれてありがとう!私は別のSOの投稿に 'ls'と' basename'部分を見つけて、それらを利用しようとしましたが、あなたが見ることができるように、うまくいきませんでした。私は文字列置換を使用して私の質問に追加した解決策が正しいことを確認してうれしいです。再度、感謝します! – Brandon

関連する問題